Параллельный ввод / вывод с использованием TPL - PullRequest
1 голос
/ 22 января 2012

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

Правильно ли, что PLINQ AsParallel() здесь не подходит, так как он разделит список идентификаторов источника, таким образом получая документы по одному разделу один за другим?

Должен ли я использовать Select() метод LINQ для преобразования списка в список Task<Document>, а затем WaitAll() в нем?

Parallel класс и AsParallel() метод расширения оба используют Task<T> внизу, не так ли? Можно ли передать локальное состояние делегатам так же, как я передаю его перегрузке Task(Action<Object>, Object)?

Ответы [ 2 ]

2 голосов
/ 22 января 2012

Использование AsParallel для IO опасно, потому что вы не можете точно контролировать степень параллелизма (DOP).Ваше устройство ввода-вывода будет иметь определенный оптимальный DOP, но это будет отличаться от того, что будет использовать TPL.

Кроме того, при вызове сетевых функций я видел, что TPL использует гораздо больше потоков, чем количество процессоров.Это приводит к перенасыщению сети и неоптимальной пропускной способности.Это также может привести к таймаутам.Я бы не стал запускать такую ​​вещь в производство из-за ее хрупкой природы.

Алгоритм, который использует TPL для выбора количества потоков, мне не совсем понятен.Я думаю, что он пытается определить, увеличивает ли пропускная способность добавление большего количества потоков, чем процессоров.Но он никогда не будет использовать меньше, чем количество процессоров.Imaging 64 потока забивает ваш веб-сервис.

Если вам нужна точная степень параллелизма, я предлагаю вам создать нужное количество задач / потоков самостоятельно.Вы можете поместить этот код в многократно используемую вспомогательную функцию ("ParallelForeachWithExactDOP").

Моя рекомендация: Если вы просто хотите запустить все, что у вас параллельно, тем самым рискуя перенасыщением и таймаутами, выдействительно может просто использовать Select, чтобы порождать все задачи одновременно.Это следует делать только в том случае, если вы знаете, что число задач будет в пределах разумного диапазона (скажем, их максимум 10).

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

1 голос
/ 22 января 2012

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

Распараллеливание с помощью веб-службы, это будет ход.

...