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?