Dado este código:
var arrayStrings = new string[1000];
Parallel.ForEach<string>(arrayStrings, someString =>
{
DoSomething(someString);
});
¿Se generarán los 1000 hilos casi simultáneamente?
fuente
Dado este código:
var arrayStrings = new string[1000];
Parallel.ForEach<string>(arrayStrings, someString =>
{
DoSomething(someString);
});
¿Se generarán los 1000 hilos casi simultáneamente?
No, no iniciará 1000 subprocesos; sí, limitará la cantidad de subprocesos que se utilizan. Parallel Extensions usa una cantidad adecuada de núcleos, en función de cuántos tiene físicamente y cuántos ya están ocupados. Asigna trabajo para cada núcleo y luego usa una técnica llamada robo de trabajo para permitir que cada subproceso procese su propia cola de manera eficiente y solo necesita realizar cualquier acceso costoso entre subprocesos cuando realmente lo necesita.
Eche un vistazo al Blog del equipo de PFX para obtener mucha información sobre cómo asigna el trabajo y todo tipo de otros temas.
Tenga en cuenta que, en algunos casos, también puede especificar el grado de paralelismo que desee.
En una máquina de un solo núcleo ... Parallel.ForEach particiona (fragmentos) de la colección en la que está trabajando entre un número de subprocesos, pero ese número se calcula en base a un algoritmo que tiene en cuenta y parece monitorear continuamente el trabajo realizado por el subprocesos que está asignando a ForEach. Entonces, si la parte del cuerpo de ForEach llama a funciones de bloqueo / enlazadas de E / S de ejecución prolongada que dejarían el hilo esperando, el algoritmo generará más hilos y reparticionará la colección entre ellos . Si los subprocesos se completan rápidamente y no se bloquean en los subprocesos IO, por ejemplo, como simplemente calcular algunos números,el algoritmo aumentará (o incluso disminuirá) el número de subprocesos hasta un punto en el que el algoritmo considere óptimo para el rendimiento (tiempo medio de finalización de cada iteración) .
Básicamente, el grupo de subprocesos detrás de todas las diversas funciones de la biblioteca Parallel funcionará con un número óptimo de subprocesos para usar. El número de núcleos de procesador físico forma solo una parte de la ecuación. NO existe una relación simple uno a uno entre el número de núcleos y el número de subprocesos generados.
No encuentro muy útil la documentación sobre la cancelación y el manejo de la sincronización de hilos. Es de esperar que MS pueda proporcionar mejores ejemplos en MSDN.
No olvide que el código del cuerpo debe escribirse para ejecutarse en varios subprocesos, junto con todas las consideraciones habituales de seguridad de subprocesos, el marco no abstrae ese factor ... todavía.
fuente
Calcula un número óptimo de subprocesos según el número de procesadores / núcleos. No todos aparecerán a la vez.
fuente
Consulte ¿Utiliza Parallel.For una tarea por iteración? para tener una idea de un "modelo mental" a utilizar. Sin embargo, el autor afirma que "al final del día, es importante recordar que los detalles de implementación pueden cambiar en cualquier momento".
fuente
Gran pregunta. En su ejemplo, el nivel de paralelización es bastante bajo incluso en un procesador de cuatro núcleos, pero con un poco de espera, el nivel de paralelización puede ser bastante alto.
Ahora mire lo que sucede cuando se agrega una operación en espera para simular una solicitud HTTP.
Aún no he realizado ningún cambio y el nivel de simultaneidad / paralelización ha aumentado drásticamente. La simultaneidad puede aumentar su límite con
ParallelOptions.MaxDegreeOfParallelism
.Recomiendo el entorno
ParallelOptions.MaxDegreeOfParallelism
. No necesariamente aumentará la cantidad de subprocesos en uso, pero garantizará que solo inicie una cantidad razonable de subprocesos, lo que parece ser su preocupación.Por último, para responder a su pregunta, no, no hará que todos los hilos comiencen a la vez. Utilice Parallel.Invoke si está buscando invocar en paralelo perfectamente, por ejemplo, probando condiciones de carrera.
fuente