Desempenho decepcionante com Parallel.For

Eu estou tentando acelerar meus tempos de cálculo usandoParallel.For. Eu tenho um processador Intel Core i7 Q840 com 8 núcleos, mas eu só consigo obter uma taxa de desempenho de 4 em comparação com um sequencialfor loop. Isso é tão bom quanto possívelParallel.For, ou o método pode ser ajustado para aumentar o desempenho?

Aqui está o meu código de teste, sequencial:

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;
}

e paralela:

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;
                    });

O loop que estou fazendo em paralelo envolve computação com uma variável definida "globalmente",sum, mas isso deve ser apenas uma pequena fração do tempo total dentro do loop paralelizado.

Na versão Release (sinalizador "otimizar código" definido) o seqüencialfor loop leva 33,7 s no meu computador, enquanto oParallel.For loop leva 8,4 s, uma taxa de desempenho de apenas 4,0.

No Gerenciador de Tarefas, vejo que a utilização da CPU é de 10 a 11% durante o cálculo sequencial, enquanto que é apenas 70% durante o cálculo paralelo. Eu tentei definir explicitamente

ParallelOptions.MaxDegreesOfParallelism = Environment.ProcessorCount

mas sem sucesso. Não está claro para mim por que nem toda a energia da CPU é atribuída aoparalelo Cálculo?

Tenho notado que uma questão semelhante foi levantada sobre SOantes, com um resultado ainda mais decepcionante. No entanto, essa questão também envolveu paralelização inferior em uma biblioteca de terceiros. Minha principal preocupação é a paralelização de operações básicas nas bibliotecas principais.

ATUALIZAR

Foi apontado para mim em alguns dos comentários que a CPU que estou usando tem apenas 4 núcleos físicos, o que é visível para o sistema como 8 núcleos se o hyper-threading estiver habilitado. Por causa disso, eu desabilitei hyper-threading e re-benchmarked.

Com hyper-threadingDesativadomeus cálculos são agoraMais rápido, tanto o paralelo e também o (o que eu pensava que era) sequencialfor loop. Utilização da CPU durante ofor loop é de aprox. 45% (!!!) e 100% durante oParallel.For loop.

Tempo de computação para ofor loop de 15,6 s (mais de duas vezes mais rápido que o hyper-threadingativado) e 6,2 s paraParallel.For (25% melhor do que quando o hyper-threading éativado). Rácio de desempenho comParallel.For é agora só2,5, rodando em 4 núcleos reais.

Portanto, a taxa de desempenho ainda é substancialmente menor que o esperado, apesar de o hyper-threading estar desativado. Por outro lado, é intrigante que a utilização da CPU seja tão alta durante ofor loop? Poderia haver algum tipo de paralelização interna acontecendo nesse loop também?

questionAnswers(4)

yourAnswerToTheQuestion