Когда параллельно увеличится производительность - PullRequest
4 голосов
/ 29 декабря 2011

Я пытаюсь понять, когда использование parallel увеличит производительность.
Я протестировал его с помощью простого кода, который выполнял более 100 000 элементов в List<Person> и изменил имя каждого из них на string.Empty.

Параллельная версия заняла в два раза больше времени, чем обычная версия. (Да, я тестировал больше с одним ядром ...)

Я видел этот ответ о том, что фрагмент данных, который не всегда параллелен, хорош для производительности.
Также это предостережение повторялось на каждой странице параллельных примеров в учебнике MSDN :

Эти примеры в первую очередь предназначены для демонстрации использования, и могут или может не работать быстрее, чем эквивалентный последовательный LINQ to Objects запросы

Мне нужны некоторые правила и советы, когда параллельность увеличит производительность моего кода, а когда нет.
Очевидный ответ: «Протестируйте свой код, если параллельный цикл использует его быстрее», абсолютно правильно, но я думаю, никто не запускал анализ производительности для каждого цикла, который он пишет.

Ответы [ 5 ]

20 голосов
/ 29 декабря 2011

Подумайте, когда стоит что-то распараллелить в реальной жизни.Когда лучше просто сесть и сделать работу самостоятельно от начала до конца, а когда лучше нанять двадцать парней?

  • Является ли работа по своей природе параллелизуемой или по своей сути последовательной?Некоторые рабочие места вообще не распараллеливаются: девять женщин не могут работать вместе, чтобы сделать одного ребенка в месяц.Некоторые задания распараллеливаются, но дают паршивые результаты: вы можете нанять двадцать парней и назначить каждому из них по пятьдесят страниц «Войны и мира», чтобы они прочитали для вас, а затем попросить каждого из них написать одну двадцатую из эссе, склеить все фрагменты эссе ипредставить документ;это вряд ли приведет к хорошей оценке.Некоторые задания очень распараллеливаемы: двадцать парней с лопатами могут вырыть яму гораздо быстрее, чем один.

  • Если работа по своей сути параллелизуема, то распараллеливание действительно экономит время?Вы можете приготовить горшок спагетти с сотней лапши в нем, или вы можете приготовить двадцать горшков спагетти с пятью лапшой в каждой и вылить результаты вместе в конце.Я гарантирую вам, что распараллеливание задачи по приготовлению спагетти не приведет к более быстрому получению обеда.

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

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

4 голосов
/ 29 декабря 2011

Если вы выполняете итерацию по коллекции и выполняете что-то, требующее больших вычислительных ресурсов для каждого элемента (особенно, если «что-то» не слишком интенсивно для ввода-вывода), вы, вероятно, увидите некоторую выгоду от распараллеливания цикла. Установка свойства string.Empty не требует больших вычислительных затрат, поэтому, вероятно, вы не получили улучшения.

2 голосов
/ 29 декабря 2011

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

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

1 голос
/ 29 декабря 2011

Для меня есть пара правил, когда вы должны подумать о распараллеливании своего кода (и даже тогда вы все равно должны проверить, чтобы проверить, быстрее ли он):

  1. Код, который вы хотите распараллелить, требует больших вычислительных ресурсов. Просто ожидание IO, как правило, не принесет вам большой выгоды. Это должно быть что-то, где вы определенно использовали бы кучу процессорного времени (например, рендеринг изображения).
  2. Код, который вы хотите распараллелить, достаточно сложен, так что накладные расходы на распараллеливание меньше, чем экономия, которую вы получаете от распространения кода (т. Е. Установка строки в строку. Пустота невероятно проста и быстра; вам понадобится что-то намного сложнее для каждого предмета, чтобы оно того стоило)
  3. Код, который вы хотите распараллелить, является независимым и не зависит от других элементов.
0 голосов
/ 30 декабря 2011

Параллелизм помогает повысить производительность только в той степени, в которой он позволяет всем аппаратным средствам вращаться в нужном направлении.

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

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

Это не делает код быстрее. Это облегчает написание.

...