F #: Asynch и Задачи и PLINQ, о мой! - PullRequest
8 голосов
/ 01 февраля 2010

Когда выйдет F #, я столкнусь с затруднениями в области асинхронного / параллельного программирования. Ответ на этот вопрос довольно хорошо описывает различия между Задачами, Parallel LINQ и Reactive Framework, но мне было интересно, как именно асинхронные рабочие процессы вписываются в картину.

Пожалуйста, исправьте меня, если я ошибаюсь, но, насколько я понимаю, асинхронные рабочие процессы будут самым простым способом работы с операциями, связанными с вводом-выводом, особенно теми, для которых определен метод AsynchXxx, или следуйте шаблону BeginXxx / EndXxx , Другое преимущество состоит в том, что асинхронные рабочие процессы являются составными и могут быть построены из других асинхронных рабочих процессов, что может обеспечить большую гибкость в структурировании программы.

Полагаю, мне нужна помощь, чтобы понять, при каких обстоятельствах я бы выбрал Tasks или PLINQ вместо асинхронных рабочих процессов в коде F #. Мне кажется, я читал, что в библиотеке параллельных задач есть более сложные способы балансировки нагрузки между ядрами. Если это так, то задачи могут быть лучшим выбором для операций с исключительно процессором, которые должны работать параллельно. PLINQ, с другой стороны, кажется, в основном, удобным способом распараллеливания существующего кода, который работает с последовательностями.

Наконец, если предположить, что мое понимание сильных сторон каждого подхода является правильным, возможно ли или целесообразно их объединить? Например, возможно, можно составить серию операций из асинхронных рабочих процессов, а затем преобразовать их в задачи перед выполнением. Если это возможно - или даже хорошая идея.

Ответы [ 2 ]

12 голосов
/ 01 февраля 2010

См. Библиотека параллельных задач и асинхронные рабочие процессы .

Я бы суммировал основы следующим образом:

Task Parallel Library : позволяет нескольким единицам работы эффективно работать на нескольких ядрах, включая относительно простые сценарии, такие как порождение нескольких потоков для параллельных вычислений, а также более сложные операции, где сами вычисления также заканчивают тем, что порождали дополнительные задачи. Использует улучшенный пул потоков .NET 4.0 и рабочие очереди кражи, чтобы гарантировать, что все ядра заняты.

Асинхронные рабочие процессы : позволяет выполнять асинхронные вычисления, не занимая ненужных потоков, и инициировать обратные вызовы, когда результаты доступны.

PLINQ : код, написанный с использованием PLINQ, в конечном итоге выполняется через TPL, но это более приятный интерфейс для кода, который легко выражается с помощью запросов LINQ (например, выполнение одной операции над каждым элементом в массиве данные параллельно).

Обратите внимание, что асинхронные рабочие процессы могут быть преобразованы в задачи с использованием метода StartAsTask, а задачи могут быть преобразованы в Async с использованием метода Async.AwaitTask, поэтому можно объединить технологии, хотя они нацелены на различные целевые сценарии.

Для меня эмпирическое правило заключается в том, что если вы активно выполняете много вычислений в разных потоках, вы захотите использовать TPL (возможно, через PLINQ или эквивалент F #, такой как модуль PSeq), тогда как если вы пытаетесь выполнить много операций ввода-вывода (параллельных или нет), вам следует использовать асинхронные рабочие процессы. Таким образом, raytracer будет использовать TPL для запуска задач для параллельного рендеринга каждого пикселя (или линии сканирования), максимизируя доступную вычислительную мощность на вашем компьютере. Но загрузка множества веб-страниц будет выполняться с помощью асинхронных рабочих процессов, так как не нужно много вычислений для распределения по ядрам; Вам просто нужно уведомить ОС, когда результаты появятся.

1 голос
/ 01 февраля 2010

Асинхронные рабочие процессы реализуются через монадический синтаксис F #. Это означает, что вместо преобразования ваших рабочих процессов в задачу вы могли бы написать собственную версию «асинхронной», основанную на библиотеке параллельных задач. Я говорю это с несколькими оговорками:

  • Это было бы трудно сделать.
  • Асинхронные операции, использующие шаблон BeginXxx / EndXxx в .NET, регистрируют обратные вызовы в пуле потоков. Я не уверен, что вы могли бы изменить это, чтобы перенаправить их, используя вместо этого задачи.

Для получения дополнительной информации о том, как реализовать монаду в F #, см. Книгу «Эксперт F #» или немного погуглите по «F # монадам».

Не полный ответ, я знаю, но надеюсь, что это немного поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...