Simultaneidade do iOS - Não atingindo o máximo teórico próximo de qualquer lugar
Eu sou novo no Grand Central Dispatch e tenho realizado alguns testes com ele fazendo algum processamento em uma imagem. Basicamente, estou executando um algoritmo em escala de cinza sequencialmente e usando o GCD e comparando os resultados.
aqui está o loop 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;
}
}
}
Ele simplesmente percorre e pega o valor médio para Vermelho, Verde e Azul e o usa para o valor cinza. Muito simples. Agora, a versão paralela basicamente divide a imagem em partes e depois calcula essas partes separadamente. Nomeadamente 2, 4, 8, 16 e 32 porções. Eu estou usando o GCD básico, então passe cada parte como seu próprio bloco para executar simultaneamente. Aqui está o código agrupado pelo 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);
Tudo está funcionando bem. Mas o que não entendo é o uso de aceleração / CPU. Executando testes no simulador (que está usando minha CPU dual core), estou recebendo:
~ 0.0945s tempo de execução sequencialmente~ 0.0675s de tempo de execução usando o GCDEsse é um aumento de aproximadamente 28% (aproximadamente, 72% do tempo da versão seqüencial). Teoricamente, em uma máquina de dois núcleos, a aceleração de 100% é o máximo. Portanto, isso está aquém disso e não consigo entender o porquê.
Monitoro o uso da CPU e o valor máximo é de cerca de 118% - por que não está chegando perto dos 200%? Se alguém tiver uma idéia do que devo mudar, ou qual é o culpado aqui, eu apreciaria muito.
Minhas teorias:
Não há trabalho suficiente na CPU (mas a imagem é ~ 3.150.000 pixels)Não há tempo suficiente para disparar até perto de 200%? Talvez cada thread exija um tempo de execução mais longo antes de começar a consumir grande parte da CPU?Eu pensei que talvez a sobrecarga fosse muito alta, mas um teste de lançamento de 32 blocos vazios em uma fila (também em um grupo) levou cerca de ~ 0,0005s no máximo.