2013-08-05 9 views
5

グランドセントラルディスパッチを使ってn個のプロセスを非同期で同時に実行できると言われました。ドキュメンテーションによると、プロセスがforループ内にある場合、関数dispatch_applyを使用できます。しかし今やそれは言っているdispatch_applyは同期または非同期ですか?

dispatch_applyは同期式なので、適用されたすべてのブロック は返されるまでに完了することに注意してください。

これは、dispatch_applyを使用してキューにサブミットされたブロックが順番に実行されることを意味しますか?もしそうなら、並行性を使用するポイントは何ですか?減速は同じではありませんか?

答えて

13

dispatch_applyは、ドキュメントに記載されているとおり、同期しています。指定されたキュー上でブロックを実行し(可能な場合)、すべてのブロックが戻るまで待機します。

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

素晴らしい、それはまさに私が何をしたいのです。ありがとう。 – Jessica

6

の目的:あなたは一度だけ非同期ブロックを実行したい場合は、あなたがあなたの現在のキューをブロックせずに並行して複数回にブロックを実行したい場合は、単にdispatch_asyncdispatch_applyを呼び出し、dispatch_asyncを使用同期dispatch_apply非同期には、利用可能な並列処理リソースに内部ループの割り込みをディスパッチします。したがって、ループ全体のパフォーマンスが向上する可能性があります。

高速ループパフォーマンス?おそらく、はい。 (警告を参照してください)

ブロック呼び出しスレッドdispatch_applyをブロックしますか?はい、完了するまでループブロックのように。 dispatch_applyまで、すべての非同期dispatch_applyが完了して作成し並列タスクを返さないので、GCD、dispatch_applyについては

同期です。

しかし、個々のタスクdispatch_applyによってがターゲットqueue非同期あるタスクかのように同時非同期に実行することができますエンキュー。スウィフトで例えば

:よう

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") 

利回り順不同出力:だから

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

dispatch_apply同期と呼ばれるブロックが、dispatch_applyによって生成されたタスクの "バッチ" を同時に実行することができ、非同期的に、互いに平行している。

注意してください...

中に実行される作業各反復は、他のすべての反復中に実行される作業 から別個であり、そして終了各 連続ループが

また重要であるため、なお内部ループ・タスクにシリアル・キューを使用してもパフォーマンスは向上しません。

シリアルキューを使用することが許されると、あなたのコードのために正しいこと をしていますが、そのようなキューを使用して所定の位置にループを残す上では実際のパフォーマンス上の利点を ありません。

0

あなたが例えばdispatch_apply()

gcl_create_dispatch_queue()を使用してパフォーマンスのスピードをアップ得ることができます:

@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 
     }); 
} 

さらに詳しい情報: OpenCL Programming Guide for Mac

関連する問題