Właściwy sposób wykonywania równoległego. Aby obliczyć dane z macierzy
chcesz: sumować x i sumować x * x. Gdzie x = linia [i]. Ponieważ więcej niż jeden wątek chce czytać / pisać do „sumAll” i „sumAllQ”, muszę zablokować jego dostęp. Problem polega na tym, że rodzaj blokady wyłącza szeregowanie tutaj. Musiałbym podzielić tę operację na # "Environment.ProcessorCount" dla pętli, z których każda sumuje jedną część tablicy i ostatecznie sumuje ich wyniki. Ale jak mogę to zrobić programowo?
Przykładowy kod:
//line is a float[]
Parallel.For(0, line.Length,
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
i =>
{
x = (double)line[i];
lock (sumLocker)
{
sumAll += x;
sumAllQ += x * x;
}
});
EDYTUJ 1: Matthew Watson odpowiada na wyniki testu porównawczego
W domu. CPU Core 2 Quad Q9550 @ 2,83 GHz:
Result via Linq: SumAll=49999950000, SumAllQ=3,33332833333439E+15
Result via loop: SumAll=49999950000, SumAllQ=3,33332833333439E+15
Result via partition: SumAll=49999950000, SumAllQ=3,333328333335E+15
Via Linq took: 00:00:02.6983044
Via Loop took: 00:00:00.4811901
Via Partition took: 00:00:00.1595113
W pracy. CPU i7 930 2,8 GHz:
Result via Linq: SumAll=49999950000, SumAllQ=3,33332833333439E+15
Result via loop: SumAll=49999950000, SumAllQ=3,33332833333439E+15
Result via partition: SumAll=49999950000, SumAllQ=3,333328333335E+15
Via Linq took: 00:00:01.5728736
Via Loop took: 00:00:00.3436929
Via Partition took: 00:00:00.0934209