0

複数の独立したタスクを並列実行するためにGrandCentralDispatchのdispatch_applyメソッドを使用して、iOSアプリを高速化しようとしています。ただし、これらのタスクは読み取り専用リソース(大きなuint8_t配列)を共有します。このリソースには、読み取り専用の非アトミックオブジェクトプロパティを介してアクセスします。読み取り専用リソースであるため、同期アクセスは必要ありません。それにもかかわらず、共有読み取り専用配列は実行を非常に遅くします。すべてのタスクのシリアル実行よりもさらに低速です。しかし、スレッドごとに配列のローカルコピーを作成すると、タスクは非常に高速に実行されます。

読み取り専用リソースの場合にGCDの恩恵を受けるために、スレッドごとにコピーを作成する必要がある理由がわかりません。GCDが読み取り専用リソースであることを認識していないために実行時間を遅くする自動内部同期が行われていますか?スレッドごとにリソースのローカルコピーを作成せずに、速度低下を防ぐことはどういうわけか可能ですか?

事前にどうもありがとうございました!

4

1 に答える 1

3

プロセッサ間でキャッシュ ラインの競合が発生している可能性があります。をどの程度正確に使用しているかは示されていませんが、 man ページdispatch_applyに記載されているストライディング戦略を実装してみてください。dispatch_applyキャッシュ ラインの競合をなくすには、ディスパッチ ワーカー スレッドが同じキャッシュ ラインを占有する共有配列の要素にアクセスしないようにすることが重要です。

配列が動的に割り当てられる場合、適切にアラインされたアドレスで開始されるため、キャッシュ ライン サイズの倍数であるストライド幅を簡単に選択できます。プロセッサのキャッシュ ライン サイズが 64 バイトの小さな倍数であると想定しても問題ないため、128、256、512、または 1024 のストライド幅が妥当です。

于 2013-02-28T14:21:16.923 に答える