Concurrencia de iOS: no alcanza el máximo teórico cercano a ninguna parte

Soy nuevo en Grand Central Dispatch y he estado realizando algunas pruebas con él procesando algo en una imagen. Básicamente estoy ejecutando un algoritmo en escala de grises tanto secuencialmente como usando GCD y comparando los resultados.

Aquí está el bucle básico:

UInt8 r,g,b;
uint pixelIndex;
for (uint y = 0; y < height; y++) {
    for (uint x = 0; x < width; x++) {
        pixelIndex = (uint)(y * width + x);

        if (pixelIndex+2 < width * height) {
            sourceDataPtr = &sourceData[pixelIndex];

            r = sourceDataPtr[0+0];
            g = sourceDataPtr[0+1];
            b = sourceDataPtr[0+2];

            int value = (r+g+b) / 3;
            if (value > MAX_COLOR_VALUE) {
                value = MAX_COLOR_VALUE;
            }

            targetData[pixelIndex] = value;
            self.imageData[pixelIndex] = value;
        }
    }
}

Simplemente se ejecuta y toma el valor promedio para Rojo, Verde y Azul y lo usa para el valor gris. Muy simple. Ahora la versión paralela básicamente divide la imagen en porciones y luego las calcula por separado. A saber 2, 4, 8, 16 y 32 porciones. Estoy usando el GCD básico, así que pase cada parte como su propio bloque para que se ejecute simultáneamente. Aquí está el código envuelto GCD:

dispatch_group_t myTasks = dispatch_group_create();

for (int startX = 0; startX < width; startX += width/self.numHorizontalSegments) {
    for (int startY = 0; startY < height; startY += height/self.numVerticalSegments) {
        // For each segment, enqueue a block of code to compute it.
        dispatch_group_async(myTasks, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
             // grayscale code...
        });
    }
}
dispatch_group_wait(myTasks, DISPATCH_TIME_FOREVER); 

Todo esta funcionando bien. Pero lo que no entiendo es el uso de CPU / aceleración. Ejecutando pruebas en el simulador (que está usando mi CPU de doble núcleo) Estoy obteniendo:

~ 0.0945s de tiempo de ejecución secuencialmente~ 0.0675s de tiempo de ejecución usando GCD

Esta es una aceleración de alrededor de ~ 28% (también conocido como 72% del tiempo de la versión secuencial). Teóricamente, en una máquina de 2 núcleos, el 100% de aceleración es el máximo. Así que esto está muy por debajo de eso y no puedo entender por qué.

Superviso el uso de la CPU y alcanza un máximo del 118%. ¿Por qué no se acerca al 200%? Si alguien tiene una idea de lo que debería cambiar, o cuál es el culpable aquí, lo agradecería enormemente.

Mis teorías

No hay suficiente trabajo en la CPU (pero la imagen es de ~ 3,150,000 píxeles)¿No tienes tiempo suficiente para disparar hasta cerca del 200%? ¿Quizás cada subproceso requiere un tiempo de ejecución más largo antes de comenzar a masticar gran parte de la CPU?Pensé que tal vez la sobrecarga era bastante alta, pero una prueba de lanzar 32 bloques vacíos a una cola (también en un grupo) tomó alrededor de ~ 0.0005s como máximo.