Я пытаюсь выяснить, почему параллельный foreach не дает ожидаемого ускорения на машине с 32 физическими ядрами и 64 логическими ядрами с помощью простого тестового вычисления.
...
var parameters = new List<string>();
for (int i = 1; i <= 9; i++) {
parameters.Add(i.ToString());
if (Scenario.UsesParallelForEach)
{
Parallel.ForEach(parameters, parameter => {
FireOnParameterComputed(this, parameter, Thread.CurrentThread.ManagedThreadId, "started");
var lc = new LongComputation();
lc.Compute();
FireOnParameterComputed(this, parameter, Thread.CurrentThread.ManagedThreadId, "stopped");
});
}
else
{
foreach (var parameter in parameters)
{
FireOnParameterComputed(this, parameter, Thread.CurrentThread.ManagedThreadId, "started");
var lc = new LongComputation();
lc.Compute();
FireOnParameterComputed(this, parameter, Thread.CurrentThread.ManagedThreadId, "stopped");
}
}
}
...
class LongComputation
{
public void Compute()
{
var s = "";
for (int i = 0; i <= 40000; i++)
{
s = s + i.ToString() + "\n";
}
}
}
Функция Compute занимает около 5секунд до завершения.Я предполагал, что в параллельном цикле foreach каждая дополнительная итерация создает параллельный поток, работающий на одном из ядер и требующий столько же, сколько требуется для вычисления функции Compute только один раз.Итак, если я запускаю цикл дважды, то с последовательным foreach это займет 10 секунд, а с параллельным foreach всего 5 секунд (при условии, что доступно 2 ядра).Ускорение составило бы 2. Если я запускаю цикл три раза, то с последовательным foreach это займет 15 секунд, но снова с параллельным foreach всего 5 секунд.Ускорение будет 3, затем 4, 5, 6, 7, 8 и 9. Однако, что я наблюдаю, это постоянное ускорение 1,3.
Последовательный и параллельный foreach.Ось X: номер последовательного / параллельного выполнения вычисления.Ось Y: время в секундах
Ускорение, время последовательного foreach, деленное на параллельный foreach
Событие, инициируемое в FireOnParameterComputed, предназначено для использования виндикатор выполнения GUI, чтобы показать прогресс.На индикаторе выполнения четко видно, что для каждой итерации создается новый поток.
Мой вопрос: почему я не вижу ожидаемое ускорение или, по крайней мере, близко к ожидаемому ускорению?