あなたが派遣グローバルキューでdispatch_applyを使用することができますがそれを並列化するために、あなたのコードは並行作業ではそれほど効率的ではないようです。アキュムレータオブジェクトは排他的アクセスを必要とし、ブロックによって緊密に使用されるため、アキュムレータオブジェクトに対して巨大なロックが発生します。
たとえば、Dispatch Global Queueでdispatch_applyを使用していても、このコードはほぼ同時ではありません。
dispatch_semaphore_t sema = dispatch_semaphore_create(1);
dispatch_queue_t queue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply([array count], queue, ^(size_t index) {
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
acc = block(acc, [array objectAtIndex:index]);
dispatch_semaphore_signal(sema);
});
dispatch_release(sema);
効率的な並列化のためにブロックとアキュムレータの実装を分割する必要があります。
EDITED:
(私はあなたのコードのアルゴリズムを確認していない。)あなたは、シリアルキューを使用している
dispatch_queue_t result_queue = dispatch_queue_create(NULL, NULL);
。シリアルキューは一度に1ブロックを実行します。したがって、それは
dispatch_queue_t result_queue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
又は
dispatch_queue_t result_queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
/* DISPATCH_QUEUE_CONCURRENT is only available OS X 10.7/iOS 4.3 or later. */
ありがとう、私はこれを既に追求しています。 dispatch_applyは、accの値を再割り当てしてセマフォーを変更しただけでは、それを気に入らないようでした。上記の私の一般的なパターンはGithubのいくつかの図書館で見ることができます。私は、これを並行して実行できる既知のアルゴリズムがあるかどうか疑問に思っていました。 –
ディスパッチキューについて更新しました。 –
DISPATCH_QUEUE_CONCURRENT定数についてのヒントをお寄せいただき、ありがとうございます.Lionのlibdispatchのアップデートを読んでいなかったので、妥当と思われる〜45%のスピードアップを得ています。 –