2013-08-05 23 views
5

Mir wurde gesagt, dass ich Grand Central Dispatch verwenden könnte, um n Prozesse gleichzeitig asynchron auszuführen. Die Dokumentation besagt, dass wenn die Prozesse in einer for-Schleife sind, ich die Funktion dispatch_apply verwenden könnte. Aber jetzt ist es zu sagenIst Dispatch_apply synchron oder asynchron?

Beachten Sie, dass dispatch_apply synchron ist, so dass alle Blöcke angewendet wird durch die Zeit abgeschlossen haben es zurückgibt.

Bedeutet dies, dass die Blöcke, die mit dispatch_apply an eine Warteschlange übergeben werden, der Reihe nach ausgeführt werden? Wenn ja, welchen Zweck hat die Verwendung von Nebenläufigkeit? Wird die Verlangsamung nicht die gleiche sein?

Antwort

13

dispatch_apply ist, wie in der Dokumentation angegeben, synchron. Es führt einen Block für die angegebene Warteschlange (falls möglich) parallel aus und wartet, bis alle Blöcke zurückgegeben werden. Wenn Sie möchten, asynchron nur einmal um einen Block laufen, verwenden dispatch_async, wenn Sie einen Block mehrfach parallel ausgeführt werden soll, ohne Ihre aktuelle Warteschlange zu blockieren, rufen Sie einfach dispatch_apply innerhalb dispatch_async:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
    dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(size_t size) { 
     NSLog(@"%lu", size); 
    }); 
}); 
+0

Awesome, das ist genau das, was ich tun möchte. Vielen Dank. – Jessica

6

Der Zweck des synchronedispatch_apply ist asynchron senden Sie die innere Schleife Interaktionen zu verfügbaren Ressourcen paralleler Verarbeitung. Somit kann die Gesamtschleifenleistung beschleunigt werden.

Schnellere Schleifenleistung? Sehr wahrscheinlich, ja. (siehe Vorbehalt)

Blockiert die Thread-Aufruf dispatch_apply? Ja, genau wie Schleifenblöcke bis zum Abschluss.

Für GCD ist dispatch_applySynchron seit dispatch_apply kehrt erst alle die asynchronen, parallel Aufgaben, die dispatch_apply abgeschlossen erstellt.

jedoch jede einzelne Aufgabe Warteschlange eingereiht durch dispatch_applyasynchrone als gleichzeitige Aufgaben ausführen kann wenn das Ziel ist queueasynchrone.

Zum Beispiel in Swift:

let batchCount: Int = 10 
let queue = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0) 
dispatch_apply(batchCount, queue) { 
    (i: Int) -> Void in 
    print(i, terminator: " ") 
} 
print("\ndispatch_apply QOS_CLASS_UTILITY queue completed") 

ergibt ungeordnete Ausgabe wie: So,

0 8 1 9 2 3 4 5 6 7 
dispatch_apply QOS_CLASS_UTILITY queue completed 

dispatch_apply synchron blockiert, wenn sie aufgerufen, aber die "Charge" von Aufgaben, die von dispatch_apply laufen gleichzeitig, asynchron, parallel zueinander.

Denken Sie daran, dass ...

die während geleistete Arbeit jede Iteration unterscheidet von der Arbeit bei allen anderen Iterationen durchgeführt, und die Reihenfolge, in der jede aufeinanderfolgende Schleife

auch unwichtig fertig ist zu beachten, dass Die Verwendung einer seriellen Warteschlange für die Aufgaben der inneren Schleife hat keinen Leistungsgewinn.

Obwohl eine serielle Warteschlange mit zulässig ist und das Richtige tut für Ihren Code, wie eine Warteschlange verwendet, hat keine wirklichen Leistungsvorteile über die Schleife an Ort und Stelle zu verlassen.

0

Sie können die Leistung Geschwindigkeit bekommen von gcl_create_dispatch_queue() mit mit dispatch_apply()

Zum Beispiel:

@import Foundation; 
@import OpenCL;  // gcl_create_dispatch_queue() 

int main() { 
     dispatch_queue_t queue = gcl_create_dispatch_queue(CL_DEVICE_TYPE_ALL, NULL); 
     dispatch_apply(10, queue, ^(size_t t) { 
      // some code here 
     }); 
} 

Weitere Informationen: OpenCL Programming Guide for Mac

Verwandte Themen