¿Cómo puedo lograr el máximo paralelismo y utilizar la CPU máxima con Parallel.ForEach?
Hay una función C #A(arg1, arg2)
que necesita ser llamado muchas veces. Para hacer esto más rápido, estoy usando programación paralela.
Tome el ejemplo del siguiente código:
long totalCalls = 2000000;
int threads = Environment.ProcessorCount;
ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = threads;
Parallel.ForEach(Enumerable.Range(1, threads), options, range =>
{
for (int i = 0; i < total / threads; i++)
{
// init arg1 and arg2
var value = A(arg1, agr2);
// do something with value
}
});
Ahora el problema es que esto no está aumentando con un aumento en el número de núcleos; p.ej. en 8 núcleos está utilizando el 80% de la CPU y en 16 núcleos está utilizando el 40-50% de la CPU. Quiero usar la CPU al máximo.
Puedes asumirA(arg1, arg2)
internamente contiene un cálculo complejo, pero no tiene operaciones de E / S ni vinculadas a la red, y tampoco hay bloqueo de subprocesos. ¿Cuáles son otras posibilidades para averiguar qué parte del código está haciendo que no funcione de manera 100% paralela?
También intenté aumentar el grado de paralelismo, p.
int threads = Environment.ProcessorCount * 2;
// AND
int threads = Environment.ProcessorCount * 4;
// etc.
Pero no fue de ayuda.
Actualización 1 - si ejecuto el mismo código reemplazandoA()
con una función simple que está calculando el número primo, entonces está utilizando 100 CPU y escalando bien. Entonces esto prueba que otro fragmento de código es correcto. Ahora el problema podría estar dentro de la función originalA()
. Necesito una forma de detectar ese problema que está causando algún tipo de secuencia.