Rozczarowująca wydajność z Parallel.For

Próbuję przyspieszyć czas obliczeń za pomocąParallel.For. Mam procesor Intel Core i7 Q840 z 8 rdzeniami, ale udaje mi się uzyskać tylko 4-krotny współczynnik wydajności w porównaniu z sekwencyjnymfor pętla. Czy to tak dobrze, jak tylko możeParallel.Forlub czy wywołanie metody można precyzyjnie dostosować, aby zwiększyć wydajność?

Oto mój kod testowy, sekwencyjny:

var loops = 200;
var perloop = 10000000;

var sum = 0.0;
for (var k = 0; k < loops; ++k)
{
    var sumk = 0.0;
    for (var i = 0; i < perloop; ++i) sumk += (1.0 / i) * i;
    sum += sumk;
}

i równolegle:

sum = 0.0;
Parallel.For(0, loops,
                k =>
                    {
                        var sumk = 0.0;
                        for (var i = 0; i < perloop; ++i) sumk += (1.0 / i) * i;
                        sum += sumk;
                    });

Pętla, która jest równoległa, polega na obliczaniu zmiennej „globalnie”,sum, ale powinno to stanowić jedynie niewielką, niewielką część całkowitego czasu w równoległej pętli.

W wersji Release (ustawiona flaga „optymalizuj kod”) sekwencyjnyfor&nbsp;pętla zajmuje 33,7 s na moim komputerze, podczas gdyParallel.For&nbsp;pętla trwa 8,4 s, współczynnik wydajności wynosi tylko 4,0.

W Menedżerze zadań widzę, że wykorzystanie procesora wynosi 10-11% podczas obliczeń sekwencyjnych, podczas gdy podczas obliczeń równoległych wynosi tylko 70%. Próbowałem wyraźnie ustawić

ParallelOptions.MaxDegreesOfParallelism = Environment.ProcessorCount

ale bez skutku. Nie jest dla mnie jasne, dlaczego nie cała moc procesora jest przypisana dorównolegle&nbsp;obliczenie?

Zauważyłem, że podobne pytanie zostało podniesione w sprawie SOprzed, z jeszcze bardziej rozczarowującym wynikiem. Jednak to pytanie wymagało również niższej równoległości w bibliotece innej firmy. Moją podstawową troską jest równoległość podstawowych operacji w bibliotekach podstawowych.

AKTUALIZACJA

W niektórych komentarzach wskazano mi, że procesor, którego używam, ma tylko 4 rdzenie fizyczne, co jest widoczne dla systemu jako 8 rdzeni, jeśli włączona jest hiperwątkowość. W tym celu wyłączyłem hiperwątkowość i ponownie przetestowałem.

Z hiperwątkowościąwyłączone, moje obliczenia są terazszybciej, zarówno równoległe, jak i (to, co myślałem) sekwencyjnefor&nbsp;pętla. Wykorzystanie procesora podczasfor&nbsp;pętla wynosi do ok. 45% (!!!) i 100% podczasParallel.For&nbsp;pętla.

Czas obliczeń dlafor&nbsp;pętla 15,6 s (ponad dwukrotnie szybciej niż w przypadku hiperwątkowości)włączone) i 6,2 s dlaParallel.For&nbsp;(25% lepsze niż w przypadku hiperwątkowościwłączone). Współczynnik wydajności zParallel.For&nbsp;jest teraz tylko2.5, działa na 4 rzeczywistych rdzeniach.

Tak więc współczynnik wydajności jest nadal znacznie niższy niż oczekiwano, pomimo wyłączenia hiperwątkowości. Z drugiej strony jest intrygujące, że wykorzystanie procesora jest tak wysokie podczasfor&nbsp;pętla? Czy w tej pętli może istnieć jakaś wewnętrzna równoległość?