2011-08-27 12 views
23

¿Hay alguna documentación válida en cuántos hilos de son creados por GCD? En WWDC, nos dijeron que está modelado alrededor de núcleos de CPU. Sin embargo, si llamo a este ejemplo:¿Número de subprocesos creados por GCD?

for (int i=1; i<30000; i++) { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     [NSThread sleepForTimeInterval:100000]; 
    }); 
} 

abre 66 hilos, incluso en un iPad1. (También abre 66 hilos cuando se llama a Lion de forma nativa). ¿Por qué 66?

Respuesta

24

Primero, 66 == 64 (el tamaño máximo del grupo de subprocesos GCD) + el subproceso principal + algún otro subproceso aleatorio no GCD.

En segundo lugar, GCD no es mágico. Está optimizado para mantener la CPU ocupada con código que está principalmente vinculado a la CPU. La "magia" de GCD es que crea dinámicamente más subprocesos que las CPU cuando los elementos de trabajo de forma involuntaria y breve esperan a que se completen las operaciones.

Habiendo dicho eso, el código puede confundir el programador de GCD al dormir intencionalmente o esperar por eventos en lugar de usar las fuentes de envío para esperar eventos. En estos escenarios, el bloque de trabajo está implementando efectivamente su propio programador y, por lo tanto, GCD debe asumir que el hilo ha sido cooptado del conjunto de subprocesos.

En resumen, el grupo de subprocesos funcionará de manera óptima si su código prefiere dispatch_after() sobre "sleep()" como API y despacha fuentes sobre bucles de eventos hechos a mano (Unix select()/poll(), Cocoa runloops o Variables de condición POSIX).

+1

"ha sido cooptado del grupo de subprocesos" ¿Qué quiere decir con la cooptación? ¿Quiere decir que el sueño u otro tipo de interrupción se interpretará como un 100% de actividad, por así decirlo, y por lo tanto, el hilo no estará disponible para su uso con despachos adicionales? –

+1

Claro que sería bueno si pudiera proporcionar una referencia para este reclamo sobre el tamaño del grupo de subprocesos: no puedo encontrar uno en ninguna parte. –

1

La documentación evita mencionar el número de subprocesos creados. Principalmente porque la cantidad óptima de hilos depende en gran medida del contexto.

Un problema con Grand Cendral Dispatch es que generará un nuevo hilo si bloquea una tarea en ejecución. Es decir, debe evitar el bloqueo cuando el uso de GCD tenga más subprocesos que núcleos y no sea óptimo.

En su caso, GCD detecta que la tarea está inactiva y genera un nuevo hilo para la siguiente tarea.

Por qué 66 es el límite que me supera.

+0

Apenas puedo creer que 66 sea un número óptimo, si la documentación me dice que cada hilo come aproximadamente medio megabyte de ram. (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html) Por lo tanto, con 66 subprocesos, tenemos alrededor de 30 megas de sobrecarga, eso es la mitad del límite de iOS de 64 MB en total. – steipete

+0

@steipete El subproceso también cuesta el cambio de contexto. Entonces la memoria no debe ser el único factor para decidir el límite. – Eonil

+1

@steipete del mismo documento "pero las páginas reales asociadas con esa memoria no se crean hasta que se necesiten". Por lo tanto, la mitad del espacio de la pila solo se reclama cuando se usa (página por página, es decir, si su hilo solo necesita 2 páginas de pila, solo desperdicia tanto). Además, Eonil, ahora tenemos CPU multinúcleo donde el costo del cambio de contexto es menos problemático (dado que 'solo' ejecuta el número de subprocesos igual o menor que el número de núcleos) – tofi9

Cuestiones relacionadas