Этот код из статьи Microsoft http://msdn.microsoft.com/en-us/library/dd460703.aspx, с небольшими изменениями:Parallel.For производительность
const int size = 10000000;
int[] nums = new int[size];
Parallel.For(0, size, i => {nums[i] = 1;});
long total = 0;
Parallel.For<long>(
0, size,() => 0,
(j, loop, subtotal) =>
{
return subtotal + nums[j];
},
(x) => Interlocked.Add(ref total, x)
);
if (total != size)
{
Console.WriteLine("Error");
}
Non-параллельная версия петли:
for (int i = 0; i < size; ++i)
{
total += nums[i];
}
Когда я измеряю время выполнения цикла, используя StopWatch
класс, Я вижу, что параллельная версия медленнее на 10-20%. Тестирование выполняется на 64-разрядной версии Windows 7, процессоре Intel i5-2400, 4 ядрах, 4 ГБ оперативной памяти. Конечно, в конфигурации Release.
В моей реальной программе я пытаюсь вычислить гистограмму изображения, а параллельная версия работает в 10 раз медленнее. Могут ли такие задачи вычислений, когда каждый вызов цикла выполняется очень быстро, успешно распараллеливаются с TPL?
Редактировать.
Наконец-то мне удалось побрить больше, чем 50% времени выполнения расчета гистограммы с помощью Parallel.For, когда разделили все изображение на некоторое количество кусков. Каждый вызов цикла цикла обрабатывает весь фрагмент, а не один пиксель.
Также имейте в виду, что Parallel.For максимизирует 64-бит. Я тестировал его в прошлом с программой, в которой Parallel.Loop обеспечивал хорошую производительность (как объясняется в ответе ниже) и заметил заметное улучшение при нацеливании проекта на x64. В этой конкретной конфигурации он был примерно в 3-4 раза быстрее (в версии x86 Parallel.Loop был уже в 5 раз быстрее, чем обычный цикл). – varocarbas
Просто для уточнения точных условий в случае моего предыдущего комментария: итеративные вычисления/хранение занимает довольно много времени. В своей первоначальной версии это заняло около 1 часа; который был сокращен примерно до 20 минут с параллельным контуром на x86 и до 5 минут с версией с 64-битным титром. Для более простых конфигураций (циклов, занимающих всего миллисекунды), довольно сложно заметно повысить производительность простого цикла. – varocarbas