Почему я не должен использовать асинхронные рабочие процессы F # для параллелизма? - PullRequest
19 голосов
/ 16 марта 2011

Я недавно изучал F #, особенно заинтересованный в его простоте использования параллелизма данных. Идиома data |> Array.map |> Async.Parallel |> Async.RunSynchronously кажется очень простой для понимания и простой в использовании и дает реальную ценность.

Так почему же async на самом деле не предназначено для этого? Сам Дональд Сайм говорит, что PLINQ и Futures, вероятно, лучший выбор. И другие ответы, которые я прочитал здесь, согласны с этим, а также рекомендуют TPL. (PLINQ не слишком сильно отличается от вышеуказанных встроенных функций, если вы используете F # Powerpack для получения функций PSeq.)

F # и функциональные языки имеют большое значение для этого, и некоторые приложения достигли больших успехов с async параллелизмом.

Так почему не следует Я использую async для выполнения параллельных процессов данных? Что я потеряю, написав параллельный async код вместо PLINQ или TPL?

Ответы [ 3 ]

15 голосов
/ 10 апреля 2011

Так почему бы мне не использовать асинхронное выполнение параллельных процессов данных?

Если у вас есть крошечное количество полностью независимых не-1005 * задач и много ядер, тогданет ничего плохого в использовании async для достижения параллелизма.Однако, если ваши задачи каким-либо образом зависят от вас, или у вас больше задач, чем у ядер, или вы слишком сильно углубляетесь в код async, то вы оставите большую производительность на столе и сможете добиться гораздо большего, есливыбирая более подходящую основу для параллельного программирования.

Обратите внимание, что ваш пример можно написать еще более элегантно, используя TPL из F #:

Array.Parallel.map f xs

Что я потеряюпри написании параллельного асинхронного кода вместо использования PLINQ или TPL?

Вы теряете возможность писать код, не обращающий внимания в кэш-памяти, и, следовательно, будете страдать от множества ошибок в кеше и, следовательно, все ядра останавливаются в ожиданииразделяемая память, что означает плохую масштабируемость в многоядерной среде.

TPL основан на идее, что дочерние задачи должны выполняться с тем же ядром, что и их родительские, с высокой вероятностью и, следовательно, выиграют от повторного использования тех же данныхпотому что будет жарко в локальном кеше процессора.С асинхронностью такой уверенности нет.

12 голосов
/ 16 марта 2011

Я написал статью, в которой повторно реализован один пример C # TPL с использованием Task и Async, в котором также есть некоторые комментарии о разнице между ними.Вы можете найти его здесь , а также есть более расширенная расширенная асинхронная версия .

Вот цитата из первой статьи, в которой сравниваются два варианта:

Выбор между двумя возможными реализациями зависит от многих факторов.Асинхронные рабочие процессы были разработаны специально для F #, поэтому они более естественно соответствуют языку.Они обеспечивают более высокую производительность для задач, связанных с вводом / выводом, и обеспечивают более удобную обработку исключений.Более того, последовательный синтаксис довольно удобен.С другой стороны, задачи оптимизированы для вычислений с привязкой к ЦП и упрощают доступ к результатам вычислений из других мест приложения без явного кэширования.

0 голосов
/ 16 марта 2011

Я всегда считал, что это то, что TPL, PLinq и т. Д. ... дают вам сверх того, что делает Async.(Механизмы отмены - тот, который приходит на ум.) На этот вопрос есть несколько лучших ответов.

Эта статья намекает на небольшое преимущество в производительности перед TPL, но, вероятнонедостаточно, чтобы быть значимым.

...