Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Не вижу принципиальных преград. Например в D есть fiber'ы.
Основная преграда это востребованность.
I>>Судя по голосовалке на этом сайте файберы использовало ажно 7% программистов
EP>7% от чего? Какой вопрос был?
Вопрос простой — использовали ли вы файберы. Проголосовало достаточно большое количество людей, что бы делать какие то выводы.
EP>Я, например, сильно сомневаюсь что хотя бы 7% от всех C#'еров использует await, или даже yield.
Гораздо больше. Асинхронщина нужна и часто апи даже не подразумевает синхронных вызовов. Колбеки, rx, tpl — всё намного сложнее, чем авайт.
Re[6]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Ikemefula, Вы писали:
EP>>Не вижу принципиальных преград. Например в D есть fiber'ы. I>Основная преграда это востребованность. I>>>Судя по голосовалке на этом сайте файберы использовало ажно 7% программистов EP>>7% от чего? Какой вопрос был? I>Вопрос простой — использовали ли вы файберы. Проголосовало достаточно большое количество людей, что бы делать какие то выводы.
IMHO — если 7% реально использовало, то это даже хорошая востребованность
А если учесть то, что появилась реально удобная и кросс-платформенная реализация, причём на самом видном месте — то процент будет только расти.
EP>>Я, например, сильно сомневаюсь что хотя бы 7% от всех C#'еров использует await, или даже yield. I>Гораздо больше.
Не верю. await появился чуть больше года назад, я сомневаюсь что на VS2012 перешло много контор.
Re[7]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>IMHO — если 7% реально использовало, то это даже хорошая востребованность EP>А если учесть то, что появилась реально удобная и кросс-платформенная реализация, причём на самом видном месте — то процент будет только расти.
Сильно вряд ли. Основной тренд это мощные локальные фичи, навроде авайта. Основная проблема не в синтексисе и удобстве а в сложности самой концепции — кооперативной многозадачности.
EP>>>Я, например, сильно сомневаюсь что хотя бы 7% от всех C#'еров использует await, или даже yield. I>>Гораздо больше.
EP>Не верю. await появился чуть больше года назад, я сомневаюсь что на VS2012 перешло много контор.
Нет особых проблем в переходе на нужный фремворк, обратная совместимость почти идеальная. Авайт очень сильно облегчает работу и позволяет убрать вагоны кода.
Re[8]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Ikemefula, Вы писали:
EP>>IMHO — если 7% реально использовало, то это даже хорошая востребованность EP>>А если учесть то, что появилась реально удобная и кросс-платформенная реализация, причём на самом видном месте — то процент будет только расти. I>Сильно вряд ли.
Согласен, но раза в 1.5 — спокойно.
I>Основной тренд это мощные локальные фичи, навроде авайта.
await и yield — это реально удобные feature, и у них очень много общего.
Нужно пытаться их обобщать — в духе C++ вводить features, которые не ограниченны несколькими конкретными применениями. Также library-only feature предпочтительней чем требующие изменения в самом языке. И один из вариантов это stackful coroutine — на основе которой реализуются и await, и yield, и многие другие features, которая реализуется как library-only.
I>Основная проблема не в синтексисе и удобстве а в сложности самой концепции — кооперативной многозадачности.
Coroutine это далеко не только кооперативная многозадачность.
I>Авайт очень сильно облегчает работу и позволяет убрать вагоны кода.
Согласен, но это не означет что все C#'исты кинулись его изучать. Многие годами ничего не изучают, не следят за новыми фичами и т.п. И как-то не верится в то, что "гораздо больше 7% C#'еров используют годовалую фичу".
Re[8]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Ikemefula, Вы писали:
I>Нет особых проблем в переходе на нужный фремворк, обратная совместимость почти идеальная.
наверно из-за идеальной совместимости тут, на рсдн, появляются темы какого гуя у мя в 4,0 работает, а в 4,5 не работает..
Re[9]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Jack128, Вы писали:
I>>Нет особых проблем в переходе на нужный фремворк, обратная совместимость почти идеальная. J>наверно из-за идеальной совместимости тут, на рсдн, появляются темы какого гуя у мя в 4,0 работает, а в 4,5 не работает..
Слово "почти" перевести что ли ?
Re[3]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, enji, Вы писали:
E>В настоящей многопоточности нужна синхронизация, а в корутинах с этим все проще. E>Так что если задача позволяет — часто корутины удобнее...
Здесь она тоже нужна, просто ты можешь вместо синхронизации — переключать нужным образом корутины. Но эти самые корутины тоже могут изменять общие данные. Настоящие потоки, кстати, имеют очень много приятных свойств, например, планировщик ОС пытается предотвращать starvation и priority inversion, планировщик меняет приоритеты потоков динамически, снижая приоритет CPU bound потоков и повышая приоритет I/O bound потоков, для того, чтобы повысить отзывчивость системы. В общем, когда люди берутся писать код на корутинах или асинхронный код на boost.asio — они часто впервые в жизни сталкиваются со всеми этими проблемами
Re[3]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Я делал тест 200k корутин (Boost.Coroutine) — полёт нормальный. Из дополнительных настроек уменьшил default размер стэка (задаётся в конструкторе).
ОС?
Re[4]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Lazin, Вы писали:
EP>>Я делал тест 200k корутин (Boost.Coroutine) — полёт нормальный. Из дополнительных настроек уменьшил default размер стэка (задаётся в конструкторе). L>ОС?
Windows 7 x64, MSVC2010SP1 x64, Boost 1.53. Должно работать и на других OS, но не проверял.
Re[5]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Lazin, Вы писали:
EP>>Windows 7 x64, MSVC2010SP1 x64, Boost 1.53. Должно работать и на других OS, но не проверял. L>А сколько на той машине памяти и свопа и какой размер стока пришлось поставить?
Но там ещё много других настроек, например нужно ли сохранять fpu регистры и т.п. 200k это не предел, например только изменив стэк на 1KiB получилось сходу запустить 400k корутин.
Re[7]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Памяти 6GiB, свопа нет. Размер стэка 10KiB.
И всего 200К корутин
Фишка async в F#/C# в том, что можно особо не думать о ресурсах, просто запускать таск на каждый чих и все будет хорошо. Это делает возможным несколько иной стиль программирования. Допустим нам нужно обработать каждый файл в директории, рекурсивно, просто запускаем таск на каждый файл или директорию, а пулл потоков будет их постепенно выполнять, пока они не закончатся. Причем таски в C# могут порождать другие таски и зависеть друг от друга. А под капотом там task stealing планировщик, как в Cilk. В boost.coroutine же нет никакого планировщика, AFAIK. В общем, на мой взгляд их не очень корректно сравнивать.
Также стоит обратить внимание на то, что ограничением в этом эксперименте является количество вирт. памяти, выделенной под стек, не количество физической памяти (там скорее всего выделяется по одной странице физ. памяти на стек). В винде есть глобальное ограничение на количество выделенной виртуальной памяти для всех процессов — commit limit. По умолчанию commit limit = размер своп файла + общий объем физичской памяти — некоторое заранее неизвестное количество памяти под нужны системы. Если процесс вылез за commit limit — он получит ООМ, даже если свободной физической памяти много. Это называется overcommit и в винде он, AFAIK, запрещен. Может быть его можно как-то разрешить, я не знаю. В linux overcommit по умолчанию разрешен, но там есть эвристический алгоритм, который может прибить процесс, ушедший в overcommit. Также, overcommit там может быть разрешен полностью или запрещен как в винде настройками. В общем, виртуальное адресное пространство — вещь не бесконечная и может быть исчерпано очень быстро. Это несколько ограничивает применимость подобных корутин на практике.
Re[8]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Lazin, Вы писали:
EP>>Памяти 6GiB, свопа нет. Размер стэка 10KiB. L>И всего 200К корутин
Я уверен что можно и больше — но нужно играться с настройками, сейчас мне это не настолько интересно.
L>Фишка async в F#/C# в том, что можно особо не думать о ресурсах, просто запускать таск на каждый чих и все будет хорошо.
У stackless корутин безусловно есть свою плюсы. Вот тут описывал
некоторые пункты.
И сейчас stackless корутины доступны для C++, только в весьма ограниченном виде (я даже как-то делал мини реализацию await в таком stackless стиле).
L>А под капотом там task stealing планировщик, как в Cilk. В boost.coroutine же нет никакого планировщика, AFAIK. В общем, на мой взгляд их не очень корректно сравнивать.
Планировщик это вообще ортогональная вещь.
await умеет работать с разными планировщиками, syncronization и execution контексты (или как-то так) — настраиваемые. Он может работать и с самодельным пулом потоков и с чем-то на подобие Boost.Asio в одном потоке. Точно также и корутины могут работать с разными планировщиками — можно с Asio использовать, а можно например с GUI Message Loop.
L>В общем, виртуальное адресное пространство — вещь не бесконечная и может быть исчерпано очень быстро. Это несколько ограничивает применимость подобных корутин на практике.
У них аллокатор стэка настраивается.
Если нужна куча долгоживущих корутин — то достаточно применить простеший аллокатор, который съест большой блок, и для аллокации просто будет делать free += requested;
Re[8]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Lazin, Вы писали:
L>Фишка async в F#/C# в том, что можно особо не думать о ресурсах, просто запускать таск на каждый чих и все будет хорошо.
Обожаю эти фразы в стиле C#/Java.
L>Это делает возможным несколько иной стиль программирования. Допустим нам нужно обработать каждый файл в директории, рекурсивно, просто запускаем таск на каждый файл или директорию, а пулл потоков будет их постепенно выполнять, пока они не закончатся. Причем таски в C# могут порождать другие таски и зависеть друг от друга. А под капотом там task stealing планировщик, как в Cilk. В boost.coroutine же нет никакого планировщика, AFAIK. В общем, на мой взгляд их не очень корректно сравнивать.
Единственное преимущество .net в данном случае — это единство синтаксиса. Т.е. запись при просто асинхронной работе или при пуле потоков и т.п. выглядит практически одинаково. А в C++ это вообще отдельные сущности. Т.е. хочется асинхронности — ставим одну библиотеку, хочется пул потоков — ставим другую, хочется одно поверх другого — сопрягаем их вместе. Естественно при этом даётся больше возможностей, чем в .net варианте, но и единого универсального синтаксиса естественно нет. Какой вариант лучше, думаю дело личных вкусов и стилей...
L>Также стоит обратить внимание на то, что ограничением в этом эксперименте является количество вирт. памяти, выделенной под стек, не количество физической памяти (там скорее всего выделяется по одной странице физ. памяти на стек). В винде есть глобальное ограничение на количество выделенной виртуальной памяти для всех процессов — commit limit. По умолчанию commit limit = размер своп файла + общий объем физичской памяти — некоторое заранее неизвестное количество памяти под нужны системы. Если процесс вылез за commit limit — он получит ООМ, даже если свободной физической памяти много. Это называется overcommit и в винде он, AFAIK, запрещен. Может быть его можно как-то разрешить, я не знаю. В linux overcommit по умолчанию разрешен, но там есть эвристический алгоритм, который может прибить процесс, ушедший в overcommit. Также, overcommit там может быть разрешен полностью или запрещен как в винде настройками. В общем, виртуальное адресное пространство — вещь не бесконечная и может быть исчерпано очень быстро. Это несколько ограничивает применимость подобных корутин на практике.
На практике? ) Вышеописанное соответствует очень узкой категории задач, типа написания высоконагруженного сервера на множество клиентов. И для таких задач есть свой набор известных по этой области решений.
Re[8]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Lazin, Вы писали:
L> В linux overcommit по умолчанию разрешен, но там есть эвристический алгоритм, который может прибить процесс, ушедший в overcommit.
Не будет. Пока процесс не начнёт трогать страницы — можно хоть 100Гб распределять.
cyberax@virtlin:~$ cat test.c
#include <stdio.h>
#include <malloc.h>
int main()
{
void * ptr = malloc(1024LL*1024*1024*60);
if (ptr)
printf("OK\n");
}
cyberax@virtlin:~$ gcc test.c
cyberax@virtlin:~$ ./a.out
OK
cyberax@virtlin:~$ free -m
total used free shared buffers cached
Mem: 4606 1999 2607 0 614 887
-/+ buffers/cache: 497 4108
Swap: 4765 12 4753
Sapienti sat!
Re[9]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>Памяти 6GiB, свопа нет. Размер стэка 10KiB. L>>И всего 200К корутин EP>Я уверен что можно и больше — но нужно играться с настройками, сейчас мне это не настолько интересно.
[...] L>>В общем, виртуальное адресное пространство — вещь не бесконечная и может быть исчерпано очень быстро. Это несколько ограничивает применимость подобных корутин на практике. EP>У них аллокатор стэка настраивается. EP>Если нужна куча долгоживущих корутин — то достаточно применить простеший аллокатор, который съест большой блок, и для аллокации просто будет делать free += requested;
Собственно тест на таком простом аллокатаре выдаёт 400k корутин по 10KiB стэка (~3.8GiB только под стэки). Всего на систему памяти 6GiB, без swap (всякие фоновые программы работают и т.п.):
Здравствуйте, Lazin, Вы писали:
L>Также стоит обратить внимание на то, что ограничением в этом эксперименте является количество вирт. памяти, выделенной под стек, не количество физической памяти (там скорее всего выделяется по одной странице физ. памяти на стек). В винде есть глобальное ограничение на количество выделенной виртуальной памяти для всех процессов — commit limit. По умолчанию commit limit = размер своп файла + общий объем физичской памяти — некоторое заранее неизвестное количество памяти под нужны системы. Если процесс вылез за commit limit — он получит ООМ, даже если свободной физической памяти много. Это называется overcommit и в винде он, AFAIK, запрещен. Может быть его можно как-то разрешить, я не знаю.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Lazin, Вы писали:
EP>>>Памяти 6GiB, свопа нет. Размер стэка 10KiB. L>>И всего 200К корутин
EP>Я уверен что можно и больше — но нужно играться с настройками, сейчас мне это не настолько интересно.
Можно и больше, но это чревато проблемами если из корутины вызывается thrid party код, который использует слишком много стека.
EP>У stackless корутин безусловно есть свою плюсы. Вот тут описывал
некоторые пункты. EP>И сейчас stackless корутины доступны для C++, только в весьма ограниченном виде (я даже как-то делал мини реализацию await в таком stackless стиле).
Я не утверждаю что оно не нужно, просто у корутин и async/await несколько разные потенциальные области применения. Посему поддержка async/await в стандарте это гуд, независимо от того, есть ли корутины в стандартной библиотеке или нет.
Re[9]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Ну я пару лент назад пытался переписать кое что на файберы, тогда еще не было boost.coroutine, поэтому все строилось на Win32 API. User mode scheduling в винде тогда тоже еще не было. В общем, я именно с этим ограничением и столкнулся. Мне не удавалось создать больше чем swap size + physical memory size стеков. С помощью изменения размера стека мне удалось запустить больше файберов, но все равно этого не хватало, поэтому пришлось продолжить использовать event based архитектуру. Потом я прочитал у Русиновича о том, что каждой странице вирт. памяти в винде должна быть сопоставлена либо страница физической памяти, либо страница в page-файле.
Re[9]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Lazin, Вы писали:
L>> В linux overcommit по умолчанию разрешен, но там есть эвристический алгоритм, который может прибить процесс, ушедший в overcommit. C>Не будет. Пока процесс не начнёт трогать страницы — можно хоть 100Гб распределять.
Мой поинт не в том, что нельзя, а в том, что такой подход не универсален, так как требует чтобы система была настроена определенным образом, а в linux можно запретить overcommit, насколько я знаю.