DM>>>Skype вообще на Delphi написан. MTD>>Что? Разве что самая первая версия.
DM>Да нет, виндовая версия 4.2 (спустя 7 лет после первой) все еще на Дельфи. Надо будет на более свежие взглянуть.
Метроскайп вообще UI на JS имеет. Внутри unmanaged com либа, видимо то самое ядро, которое пилится с бородатых времен.
Здравствуйте, Ikemefula, Вы писали:
I>>>Очевидно — нет.
M>>А что у него вместо "stack switching model"?
I>По коду метода генерируется класс который поддерживает нужный интерфейс. Соответсвенно не надо никаких фокусов со стеком.
В смысле "нужный интерфейс"? То есть код метода нарезается на несколько методов, которые потом дёргаются при наступлении соответствующих асинхронных событий? Так?
Здравствуйте, Mazay, Вы писали:
I>>>>По моему это есть всяких сортов пляски. Хотя я не уверен, давно пора пляски с памятью и стеком сделать частью языка С++, как это было сделано со смартпоинтерами. Тогда уж точно нельзя будет придраться FR>>>Как будто код с async который ты чуть выше привел не занимается за кулисами тем же самым. I>>Очевидно — нет. M>А что у него вместо "stack switching model"?
C#-ый async/await это фактически stackless coroutine.
Компилятор автоматически генерирует класс-конечный автомат. Локальные переменные оригинальной функции переносятся в поля этого класса, а весь код в метод класса который в зависимости от текущего state прыгает по switch на нужный await.
В C++ stackless coroutine реализуется 100-ми строчками, например как в Boost.Asio. Локальные переменные(если таковые имеются) переместить в поля класса нужно вручную, а в остальном всё схоже по форме и содержанию — например конечный автомат (с таким же switch'ем внутри) генерируется автоматически.
Stackless coroutine менее мощные чем stackful — если бы это было не так, то как минимум никто бы не реализовывал Boost.Coroutine.
Одна из фишек stackful coroutine в том, что можно инкапсулировать всю асинхронную логику во внутрь компонентов — так, что клиентский код будет выглядеть как синхронный — без всяких keywords и дополнительных вызовов.
Например, в examples к Boost.Coroutine есть пример простого сервера, который асинхронно считывает сообщения из tcp порта и выводит их на экран — причём всё это происходит в одном потоке. Цикл считывания выглядит точно также как и обыкновенный синхронный код:
Вся асинхронная логика спрятана в клиентский поток: внутри, после async_read_some делается yield, а когда придут данные — сопроцедура будится соответствующим хэндлером.
На stackless coroutine такая инкапсуляция не получится — асинхронные кишки будут торчать в клиентском коде, ибо такие сопроцедуры сразу возвращают управление в клиентский код — а это значит что либо данные ещё не получены, либо никакой асинхронности, так как только один поток.
Здравствуйте, gandjustas, Вы писали:
EP>>Если активный режим процессора это один из главных потребителей зарядки, то уменьшение такого времени — будет уменьшать потребление G>неверно. Смысл какой уменьшать этот один процент до 0.5%? Ну станет зарядка держать на 2-3 минуты дольше. А если ты эффективнее IO сделаешь в 2 раза, то сохранишь 4,5% зарядки, что будет уже 10-15 минут.
Это ты сам себе придумал. Процы жрут и очень много, раз в 10-20 больше любого "IO" в виде HDD.
Здравствуйте, fddima, Вы писали:
F>Здравствуйте, gandjustas, Вы писали:
EP>>>Если активный режим процессора это один из главных потребителей зарядки, то уменьшение такого времени — будет уменьшать потребление G>>неверно. Смысл какой уменьшать этот один процент до 0.5%? Ну станет зарядка держать на 2-3 минуты дольше. А если ты эффективнее IO сделаешь в 2 раза, то сохранишь 4,5% зарядки, что будет уже 10-15 минут. F> Это ты сам себе придумал. Процы жрут и очень много, раз в 10-20 больше любого "IO" в виде HDD.
Если поделить энергопортебление на среднее время работы, то процы не обгоняют SSD и вай-фай если что.
Только если видео на планшете смотришь в HD, то проц заметно напрягается и кушает батарейку.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Mazay, Вы писали:
EP>Stackless coroutine менее мощные чем stackful — если бы это было не так, то как минимум никто бы не реализовывал Boost.Coroutine.
Совсем наоборот, но в C++ таки требуются минимум 100 строк и еще какие-то пляски чтобы не хранить стек, поэтому и делают stackful.
Хранение стека по определению менее масштабируемо, ибо надо хранить весь стек, который по дефолту — 1мб и примерно на 200 потоках\файберах кончается. Хз как внутри устроен Boost.Coroutine, но мне кажется что именно так.
Но самое главное что хрен ты это дело запустишь на нескольких ядрах.
Здравствуйте, gandjustas, Вы писали:
EP>>Stackless coroutine менее мощные чем stackful — если бы это было не так, то как минимум никто бы не реализовывал Boost.Coroutine. G>Совсем наоборот, но в C++ таки требуются минимум 100 строк и еще какие-то пляски чтобы не хранить стек, поэтому и делают stackful.
100 строк это библиотечный код, который пишется один раз
И да, синтаксического сахара в async/await больше.
G>Хранение стека по определению менее масштабируемо, ибо надо хранить весь стек, который по дефолту — 1мб и примерно на 200 потоках\файберах кончается. Хз как внутри устроен Boost.Coroutine, но мне кажется что именно так.
Размер стэка там задаётся — хоть 10KiB, хоть 100KiB, причём можно использовать свой аллокатор.
G>Но самое главное что хрен ты это дело запустишь на нескольких ядрах.
EP>C#-ый async/await это фактически stackless coroutine. EP>Компилятор автоматически генерирует класс-конечный автомат. Локальные переменные оригинальной функции переносятся в поля этого класса, а весь код в метод класса который в зависимости от текущего state прыгает по switch на нужный await.
Понятно.
EP>В C++ stackless coroutine реализуется 100-ми строчками, например как в Boost.Asio. Локальные переменные(если таковые имеются) переместить в поля класса нужно вручную, а в остальном всё схоже по форме и содержанию — например конечный автомат (с таким же switch'ем внутри) генерируется автоматически.
Вообще-то выделенное весьма неприятно. Как и в лямбдах, по умолчанию всё это надо бы делать автоматически, хотя ручной контроль и может быть иногда полезен.
EP>Например, в examples к Boost.Coroutine есть пример простого сервера, который асинхронно считывает сообщения из tcp порта и выводит их на экран — причём всё это происходит в одном потоке. Цикл считывания выглядит точно также как и обыкновенный синхронный код: EP>
EP>Вся асинхронная логика спрятана в клиентский поток: внутри, после async_read_some делается yield, а когда придут данные — сопроцедура будится соответствующим хэндлером.
Это да. Я такое делал ещё до бустовых сопроцедур. Вроде бы обычная процедура, но таких можно запустить аж 1000 на 4 потоках . Главное чтоб системных хендлеров хватало.
EP>На stackless coroutine такая инкапсуляция не получится — асинхронные кишки будут торчать в клиентском коде, ибо такие сопроцедуры сразу возвращают управление в клиентский код — а это значит что либо данные ещё не получены, либо никакой асинхронности, так как только один поток.
Вроде бы в C# синтаксис и компилятор всё это аккуратно прячут.
EP>>Stackless coroutine менее мощные чем stackful — если бы это было не так, то как минимум никто бы не реализовывал Boost.Coroutine. G>Совсем наоборот, но в C++ таки требуются минимум 100 строк и еще какие-то пляски чтобы не хранить стек, поэтому и делают stackful. G>Хранение стека по определению менее масштабируемо, ибо надо хранить весь стек, который по дефолту — 1мб и примерно на 200 потоках\файберах кончается. Хз как внутри устроен Boost.Coroutine, но мне кажется что именно так.
Однако не согласен. Стэка используется не больше чем необходимо по логике алгоритма. В контексте сопроцедур хранятся только регистры, в том числе стэковые (SP, BP). Копий всего стэка никто не делает. Так что переключение конекста между не может быть сильно дороже простого вызова функции, там ведь тоже регистры в стэк сбрасываются/извлекаются. Другое дело, что это концептуально не так симпатично может быть. Но кого это волнует?
G>Но самое главное что хрен ты это дело запустишь на нескольких ядрах.
Неправда. Я делал, в моём случае работало. И не могу вообще здесь проблему представить .
Здравствуйте, Mazay, Вы писали:
EP>>В C++ stackless coroutine реализуется 100-ми строчками, например как в Boost.Asio. Локальные переменные(если таковые имеются) переместить в поля класса нужно вручную, а в остальном всё схоже по форме и содержанию — например конечный автомат (с таким же switch'ем внутри) генерируется автоматически. M>Вообще-то выделенное весьма неприятно. Как и в лямбдах, по умолчанию всё это надо бы делать автоматически, хотя ручной контроль и может быть иногда полезен.
Не спорю, немного сахара не повредило бы. Но с основной задачей — автогенерацией конечного автомата — он справляется.
M>Это да. Я такое делал ещё до бустовых сопроцедур. Вроде бы обычная процедура, но таких можно запустить аж 1000 на 4 потоках . Главное чтоб системных хендлеров хватало.
Только что запустил 200000 boost'овых сопроцедур в одном потоке — полёт нормальный.
Пробег по всем — MSVC2010x64 около 0.06s (два переключения контекста на одну сопроцедуру — в неё и обратно в планировщик). Но я ничего не настраивал, судя по документации можно получить на порядок более быстрое переключение. Хотя и такой скорости с головой хватит во многих случаях.
EP>>На stackless coroutine такая инкапсуляция не получится — асинхронные кишки будут торчать в клиентском коде, ибо такие сопроцедуры сразу возвращают управление в клиентский код — а это значит что либо данные ещё не получены, либо никакой асинхронности, так как только один поток. M>Вроде бы в C# синтаксис и компилятор всё это аккуратно прячут.
Не всё: когда клиентскому коду нужен результат async метода — то он либо вызывает блокирующий Task.Wait() (в этом случае теряется либо асинхронность, либо однопоточность), либо await и при этом сам становится async методом (что в свою очередь влияет на весь код который его использует).
А в коде из примера Boost.Coroutine нет никаких признаков асинхронности.
Здравствуйте, IT, Вы писали:
IT>Т.е. больше в стандарте описывать нечего?
Оно всегда там было в виде страшного и ужасного auto_ptr.
auto_ptr теперь отправили на пенсию, а чтоб было не скучно, добавили пару
новых шибко умных указателей
IT>А я и думаю, почему это последние стандарты языка вызывают у публики такую, мягко говоря, неоднозначную реакцию.
Ага есть такое, если кратко, не любят это:
auto f = [](){};
Так и шарпщики же далеко не все одобряют var и linq.
G>Еще раз: продолжения+детерминированная финализация. Вместе, а не по-отдельности. В общем случае нельзя придумать способ гарантированной очистки памяти. Продолжение может просто не вызваться и будет держать ссылку на замыкание.
GC же тоже будет держать в таких случаях.
G>В некоторых условиях можно, но условия будут постоянно меняться от структуры кода. замучаешься следить.
Как показывает практика использования тех же замыканий в C++ следить не сложно.
EP>Stackless coroutine менее мощные чем stackful — если бы это было не так, то как минимум никто бы не реализовывал Boost.Coroutine. EP>Одна из фишек stackful coroutine в том, что можно инкапсулировать всю асинхронную логику во внутрь компонентов — так, что клиентский код будет выглядеть как синхронный — без всяких keywords и дополнительных вызовов.
Stackless тоже можно сделать выглядящим как синхронный, но нужен сахар или встроенный в компилятор
или с помощью монад.
Здравствуйте, IT, Вы писали:
IT>А их отправят в следующем стандарте?
Это вряд-ли, стандарты сейчас обещают часто выпекать, уже в следующем
году будет еще один.
FR>>Так и шарпщики же далеко не все одобряют var и linq.
IT>Не любят в основном те, кто в этом не смог разобраться. За это и не любят.
J>arg1 по значению, arg2 по расшаренной ссылке. Можно и не по расшаренной, кстати, если нет необходимости ее шарить, а нужно просто передавать от одной функции к другой — тогда достаточно простого unique_ptr, у которого вообще никаких накладных расходов.
Это неинтересно. Ты мне покажи, как будет устроен код для, скажем, скачивания файла.
Или банальная штука, которая читает данные из базы и выплёвывает отформатированный HTML в соединение.
При этом спать в потоке нельзя: это просёр ценного адресного пространства, которое нужно другим. И буферить вообще всё — тоже нельзя, это просёр ценного адресного пространства. Всё — только через IOCP.
И, пожалуйста, без утечек соединений и памяти.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Mazay, Вы писали:
M>В смысле "нужный интерфейс"? То есть код метода нарезается на несколько методов, которые потом дёргаются при наступлении соответствующих асинхронных событий? Так?
Примерно так. Метод превращается в state-machine, которую на более отсталых языках надо выписывать вручную.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, D. Mon, Вы писали:
DM>Здравствуйте, MTD, Вы писали:
DM>>>Google Chrome — обертка над WebKit, который тянется с прошлого века (Initial release November 4, 1998). MTD>>Отчего его в .Net не обернули?
DM>Не было смысла, полагаю.
Как же так? Ведь плюсы умирают, писать на них ад, грабля на грабле и т.д.
Здравствуйте, Mazay, Вы писали:
I>>По коду метода генерируется класс который поддерживает нужный интерфейс. Соответсвенно не надо никаких фокусов со стеком.
M>В смысле "нужный интерфейс"? То есть код метода нарезается на несколько методов, которые потом дёргаются при наступлении соответствующих асинхронных событий? Так?