| 1 2 |
| Generators 2 | |
| От: | remark | ||
| Дата: | 28.05.08 09:36 | ||
| Оценка: | 39 (7) | ||
| Немного пропатчил версию c-smile: http://www.rsdn.ru/forum/message/2965247.1.aspx Автор: c-smile Дата: 27.05.08 Дабы пофиксить следующие вещи, которые всплыли при первой же попытке реально применить Generators:
И ещё добавил, что можно писать return посередине функции генерации. Использование теперь выглядит так:
Реализация:
Теперь стало использовать немного попроще. Вот, например, обход дерева в глубину. Кстати, если нужны локальные переменные внутри функции генерации, то их можно брать в expression block {}.
|
| Re: Generators 2 | |
| От: | remark | ||
| Дата: | 28.05.08 09:45 |
| Здравствуйте, remark, Вы писали: R>Теперь стало использовать немного попроще. Вот, например, обход дерева в глубину. ---------------------------------------------------------------------/\/\/\/\ ------------------------------------------------------------------рекурсивный R>
R> |
| Re: Generators 2 | |
| От: | Alexander G | ||
| Дата: | 28.05.08 09:50 |
| Здравствуйте, remark, Вы писали: R>Немного пропатчил версию c-smile: R>http://www.rsdn.ru/forum/message/2965247.1.aspx Автор: c-smile Дата: 27.05.08 Что-то сомневаюсь что из этого может получится что-то практически полезное. Считаю, что такое лучше делать через настоящие сопрограммы. В windows — на фиберах, как здесь. Как сделать на других платформах — думаю, можно глянуть в Boost.Coroutine |
| Re[2]: Generators 2 | |
| От: | remark | ||
| Дата: | 28.05.08 10:37 |
| Здравствуйте, Alexander G, Вы писали: AG>Здравствуйте, remark, Вы писали: R>>Немного пропатчил версию c-smile: R>>http://www.rsdn.ru/forum/message/2965247.1.aspx Автор: c-smile Дата: 27.05.08 AG>Что-то сомневаюсь что из этого может получится что-то практически полезное. AG>Считаю, что такое лучше делать через настоящие сопрограммы. В windows — на фиберах, как здесь. Как сделать на других платформах — думаю, можно глянуть в Boost.Coroutine А сколько они "весят"? По объёму занимаемой памяти и по времени переключения контекста? У меня есть подозрение, что значиииииииительно дороже, чем предложенное решение. Чем несколько байт + 1 переход. Я думал делать на фиберах даже более существенную вещь, но отказался, т.к. потенциально надо будет создавать миллионы. |
| Re[3]: Generators 2 | |
| От: | Alexander G | ||
| Дата: | 28.05.08 11:12 |
| Здравствуйте, remark, Вы писали: R>Здравствуйте, Alexander G, Вы писали: R>А сколько они "весят"? По объёму занимаемой памяти и по времени переключения контекста? R>У меня есть подозрение, что значиииииииительно дороже, чем предложенное решение. Чем несколько байт + 1 переход. R>Я думал делать на фиберах даже более существенную вещь, но отказался, т.к. потенциально надо будет создавать миллионы. Я понял. Но если итератор итерирует по большим бинарным блокам, читаемым из файла, то оверхед на переключение незаметен, а вот прикрутить эту идею к последовательному чтению файла сложнее. Была задача обрабатывать поток бинарных данных несколькими независимыми способами. Решение было читать кусками, передавать данные в каждый способ через враппер, который делает yield, как только пытается анализировать ещё не прочитанные данные, yield другому способу, когда все способы дошли до yield, читать следующую порцию и вернуть управление способам. В этом случае оверхед от фиберов не чуствовался. R> |
| Re[3]: Generators 2 | |
| От: | Roman Odaisky | ||
| Дата: | 28.05.08 12:00 |
| Здравствуйте, remark, Вы писали: AG>>Считаю, что такое лучше делать через настоящие сопрограммы. В windows — на фиберах, как здесь. Как сделать на других платформах — думаю, можно глянуть в Boost.Coroutine R>А сколько они "весят"? По объёму занимаемой памяти и по времени переключения контекста? R>У меня есть подозрение, что значиииииииительно дороже, чем предложенное решение. Чем несколько байт + 1 переход. Там переключение контекста должно быть безъядерное, так что оверхед должен быть мал. R>Я думал делать на фиберах даже более существенную вещь, но отказался, т.к. потенциально надо будет создавать миллионы. А пробовал? В POSIX, кстати, уже лет 7 есть {get,set,swap}context. status=sent (delivered to file: /dev/null) |
| Re[4]: Generators 2 | |
| От: | remark | ||
| Дата: | 28.05.08 12:38 |
| Здравствуйте, Roman Odaisky, Вы писали: RO>Здравствуйте, remark, Вы писали: AG>>>Считаю, что такое лучше делать через настоящие сопрограммы. В windows — на фиберах, как здесь. Как сделать на других платформах — думаю, можно глянуть в Boost.Coroutine R>>А сколько они "весят"? По объёму занимаемой памяти и по времени переключения контекста? R>>У меня есть подозрение, что значиииииииительно дороже, чем предложенное решение. Чем несколько байт + 1 переход. RO>Там переключение контекста должно быть безъядерное, так что оверхед должен быть мал. Мал — это понятие растяжимое. Тут оверхед получается несколько машинных инструкций, при соотв. встраивании. R>>Я думал делать на фиберах даже более существенную вещь, но отказался, т.к. потенциально надо будет создавать миллионы. RO>А пробовал? RO>В POSIX, кстати, уже лет 7 есть {get,set,swap}context. Даже не стал пробовать. Основная проблема — память под стек. Фиберу-то нужен полноценный стек. Ведь не запретишь в функции писать "char temp_buf [4096];", и потом стек вызовов может быть достаточно длинный, включая всякие сторонние библиотеки. Т.е. меньше, чем 64k не отделаешься. На переключение тоже оверхед по времени будет определенный. Хоть ядра не будет, но всё же, я думаю не менее 50 тактов. А у меня сейчас полный цикл, включающий шедулер и ещё несколько других вещей, — 50 тактов. А по поводу юниксов, всё ещё хуже. Ситуация практически комическая, в винду фиберы пришли из юниксов и укоренились, а в юниксах они теперь депрекейтед: http://article.gmane.org/gmane.comp.lib.boost.threads.devel/316 Правда, я не думаю, что ucontext исчезнет в обозримом будущем, потомучто слишком много кода уже на него завязано... |
| Re[5]: Generators 2 | |
| От: | Roman Odaisky | ||
| Дата: | 28.05.08 12:52 |
| Здравствуйте, remark, Вы писали: R>А по поводу юниксов, всё ещё хуже. Ситуация практически комическая, в винду фиберы пришли из юниксов и укоренились, а в юниксах они теперь депрекейтед: R> R>http://article.gmane.org/gmane.comp.lib.boost.threads.devel/316 А почему? status=sent (delivered to file: /dev/null) |
| Re[6]: Generators 2 | |
| От: | remark | ||
| Дата: | 28.05.08 12:54 |
| Здравствуйте, Roman Odaisky, Вы писали: RO>Здравствуйте, remark, Вы писали: R>>А по поводу юниксов, всё ещё хуже. Ситуация практически комическая, в винду фиберы пришли из юниксов и укоренились, а в юниксах они теперь депрекейтед: R>> R>>http://article.gmane.org/gmane.comp.lib.boost.threads.devel/316 RO>А почему? Теперь у них есть потоки! Нафиг им фиберы? Вообще я не знаю. |
| Re[5]: Generators 2 | |
| От: | Alexander G | ||
| Дата: | 28.05.08 13:28 |
| Здравствуйте, remark, Вы писали: R>Даже не стал пробовать. Основная проблема — память под стек. Фиберу-то нужен полноценный стек. Ведь не запретишь в функции писать "char temp_buf [4096];", и потом стек вызовов может быть достаточно длинный, включая всякие сторонние библиотеки. Т.е. меньше, чем 64k не отделаешься. На счёт памяти понятно, но это один контекст на один активный итератор. Кстати на повторном выделении можно сэкономить используя пул фиберов. R>На переключение тоже оверхед по времени будет определенный. Хоть ядра не будет, но всё же, я думаю не менее 50 тактов. А у меня сейчас полный цикл, включающий шедулер и ещё несколько других вещей, — 50 тактов. Насколько я понимаю в фиберах переключаются всего лишь регистры, без FPU контекста. Это действительно 50 тактов ? |
| Re[6]: Generators 2 | |
| От: | remark | ||
| Дата: | 28.05.08 13:57 |
| Здравствуйте, Alexander G, Вы писали: AG>На счёт памяти понятно, но это один контекст на один активный итератор. Кстати на повторном выделении можно сэкономить используя пул фиберов. AG>Насколько я понимаю в фиберах переключаются всего лишь регистры, без FPU контекста. Это действительно 50 тактов ? Померить можно, но я не буду, т.к. по памяти меня уже не устраивает. Всё-таки проигрыш в 2000 раз это серьезно, и существенно ограничивает область применения. |
| Re[7]: Generators 2 | |
| От: | Alexander G | ||
| Дата: | 28.05.08 17:57 |
| Здравствуйте, remark, Вы писали: R>Померить можно, но я не буду, т.к. по памяти меня уже не устраивает. Всё-таки проигрыш в 2000 раз это серьезно, и существенно ограничивает область применения. А если задать размер стека по минимуму ?
|
| Re[8]: Generators 2 | |
| От: | remark | ||
| Дата: | 28.05.08 18:54 |
| Здравствуйте, Alexander G, Вы писали: AG>Здравствуйте, remark, Вы писали: R>>Померить можно, но я не буду, т.к. по памяти меня уже не устраивает. Всё-таки проигрыш в 2000 раз это серьезно, и существенно ограничивает область применения. AG>А если задать размер стека по минимуму ?
... тогда всё свалится в какой-то момент от нехватки стека. |
| Re[8]: Generators 2 | |
| От: | Erop | ||
| Дата: | 28.05.08 19:06 |
| Здравствуйте, Alexander G, Вы писали: AG>А если задать размер стека по минимуму ?
А зачем хаккерить? Неужели рещение с легко пререполняемым стеком тебе кажется надёжнее и поддерживаемее, чем химия с макросами? Про то, что рабоать всем генераторам на одном стеке выгоднее и по памяти и по использованию кэша я вообще ине говорю, даже... Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском |
| Re[9]: Generators 2 | |
| От: | Alexander G | ||
| Дата: | 29.05.08 06:04 |
| Здравствуйте, Erop, Вы писали: E>А зачем хаккерить? Неужели рещение с легко пререполняемым стеком тебе кажется надёжнее и поддерживаемее, чем химия с макросами? Поддерживаемее — да. Можно использовать локальные переменные без ограничений. Можно использовать подпрограммы и передавать yield туда (включая чужой код, доступный только в бинарном виде). Вообще никаких искусственных синтаксических ограничений и ничего не препятствует лёгкой вставке такого yield в существующие циклы, как и обратной операции. |
| Re[10]: Generators 2 | |
| От: | Erop | ||
| Дата: | 29.05.08 06:24 |
| Здравствуйте, Alexander G, Вы писали: AG>Можно использовать локальные переменные без ограничений. Можно использовать подпрограммы и передавать yield туда (включая чужой код, доступный только в бинарном виде). Вообще никаких искусственных синтаксических ограничений и ничего не препятствует лёгкой вставке такого yield в существующие циклы, как и обратной операции. Ну, как бы, всегда можно написать state machine вообще без хаккерства. Хотя я согласен, что эти генераторы с STL не компатибл совсем. Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском |
| Re: Generators 2 | |
| От: | sokel | ||
| Дата: | 29.05.08 06:59 |
| Здравствуйте, remark, Вы писали: R>Теперь стало использовать немного попроще. Вот, например, обход дерева в глубину. Извиняюсь за оффтоп, просто недавно тоже встала задача такого обхода дерева. В целях уменьшения объемов данных использую легковесные бинарные деревья, без хранения leftmost нод. То есть искать по ним через root можно, но вот чтобы обойти все элементы, приходится получать begin() левым спуском, хотя для обхода может быть даже не важен порядок. Насколько я знаю, stl-реализации деревьев иногда используют рекурсию (например, при очистке), поскольку глубина всё таки, исходя из самой идеи дерева, не может быть очень уж большой. Так что тут может самодельный стек и излишен. У меня вот всё обошлось указателем на функцию с шаблонным параметром, что-то вроде:
|
| Re: Generators 2 | |
| От: | R.K. | ||
| Дата: | 29.05.08 15:35 | ||
| Оценка: | 33 (3) | ||
| Здравствуйте, remark, Вы писали: R>Немного пропатчил версию c-smile: R>http://www.rsdn.ru/forum/message/2965247.1.aspx Автор: c-smile Дата: 27.05.08 Если поменять еще немного, можно организовать взаимнорекурсивные генераторы
То, что я хочу переписать на с++: Re[22]: Write in Nemerle! Автор: R.K. (и дальше по теме)...Дата: 04.12.06
You aren't expected to absorb this |
| Re[2]: Generators 2 | |
| От: | frogkiller | ||
| Дата: | 29.05.08 20:14 |
| Здравствуйте, R.K., Вы писали: RK>То, что я хочу переписать на с++: Re[22]: Write in Nemerle! Автор: R.K. (и дальше по теме)...Дата: 04.12.06 RK>
Ну и какой результат на P4-2.8? У меня на Athlon64 X2, 3800+, 1 Гб оперативки — 0.641 сек. Собирал древним gcc 3.4.2 (MinGW, CodeBlocks под WinXP SP2) Курица — это инструмент, с помощью которого одно яйцо производит другие. |
| Re: Generators 2 | |
| От: | frogkiller | ||
| Дата: | 29.05.08 20:16 |
| Здравствуйте, remark, Вы писали: R>Немного пропатчил версию c-smile: R>http://www.rsdn.ru/forum/message/2965247.1.aspx Автор: c-smile Дата: 27.05.08 Немного позанудствую:
R> Курица — это инструмент, с помощью которого одно яйцо производит другие. |
| 1 2 |