¿Cuál es la implementación correcta para hacer que dispatch_apply ejecute más de un hilo simultáneo en el iPhone?

La API de GCD describe la asincronía, pero no necesariamente la concurrencia y definitivamente no el enhebrado. Como tal, se esfuerza por hacer el uso más eficiente de los recursos del dispositivo.

En una máquina multinúcleo que puede significar ejecutar múltiples bloques simultáneamente en múltiples núcleos. Pero en una máquina de un solo núcleo, como la mayoría de los iPhones, agregar subprocesos adicionales para ejecutar múltiples bloques al mismo tiempo simplemente conlleva una sobrecarga de cambio de contexto, lo que significa un uso menos eficiente del hardware (y recuerde, la eficiencia de la CPU se traduce en la duración de la batería).

Por lo tanto, GCD no es la herramienta adecuada para garantizar la concurrencia sin tener en cuenta el uso óptimo del dispositivo. En cambio, los hilos o algún análogo de corutinas pueden ser más adecuados para lograr su objetivo.

Por otro lado, si simplemente desea programar asincrónicamente algún trabajo para que se realice de la manera más eficiente, independientemente del dispositivo en el que su código termine implementado, GCD es la herramienta adecuada para el trabajo. ¡Y también serializa!

El uso de dispatch_apply permite la concurrencia, pero no la requiere. La documentación indica que “el bloque puede invocarse simultáneamente” (el énfasis es mío). Si los pases múltiples son concurrentes depende de si GCD piensa que hacerlo es un uso eficiente de los recursos. Los factores que afectan esa decisión, por supuesto, incluirán la cantidad de núcleos de CPU disponibles, pero también pueden incluir otras cosas.

Lo bueno de dispatch_apply es que al usarlo ya está codificando para aprovechar futuras mejoras de hardware. Si Apple presentara un iPhone de cuatro núcleos, su código ya sabe cómo utilizar los núcleos adicionales.

Por otro lado, si lo que desea es una ejecución concurrente real en lugar de “simplemente” distribuir eficientemente el trabajo en múltiples núcleos, entonces dispatch_apply probablemente no sea la mejor opción.