背景:C ++ AMPの概要については、DanielMothの最近のBUILDトークを参照してください。
ここ、ここ、ここ、そしてここで最初のウォークスルーを通過します。
その最後の参照でのみ、彼らはを呼び出しますarray_view.synchronize()
。
これらの簡単な例では、への呼び出しsynchronize()
は不要ですか?いつ除外しても安全ですか?parallel_for_eachがそれなしで「同期的に」動作することを信頼できますか(進行中のコードなし)?
array_viewインターフェースを経由せずにデータにアクセスする場合は、synchronize()を使用します。データへのすべてのアクセスでarray_view演算子と関数を使用する場合は、synchronize()を使用する必要はありません。ダニエルが述べたように、array_viewのデストラクタも同期を強制します。その場合は、スローされる可能性のある例外を取得できるように、synchronize()を呼び出すことをお勧めします。
同期機能は、呼び出しコンテキスト内のバッファーを強制的に更新します。つまり、GPUにデータを書き込んでから、CPUコードで同期を呼び出すと、更新された値がCPUメモリにコピーされます。
これは名前から明らかなようですが、他のarray_view操作でも「同期」が発生する可能性があるためです。C ++ AMP array_viewは、CPUとGPUメモリ間のコピーを暗黙的に行うように最善を尽くします。配列ビューインターフェイスを介してデータを読み取る操作でも、コピーが発生します。
std::vector<int> v(10);
array_view<int, 1> av(10, v);
parallel_for_each(av.grid, [=](index<1> i) restrict(direct3d) {
av[i] = 7;
}
// at this point, data isn't copied back
std::wcout << v[0]; // should print 0
// using the array_view to access data will force a copy
std::wcout << av[0]; // should print 7
// at this point data is copied back
std::wcout << v[0]; // should print 7
my_array_view_instance.synchronizeは、デストラクタがsynchronizeを呼び出すため、ここで示した単純な例には必要ありません。そうは言っても、明示的に同期を呼び出すというベストプラクティス(申し訳ありません)に従っていません。その理由は、その時点で例外がスローされた場合、それらをデストラクタに任せても監視されないため、明示的にsynchronizeを呼び出してください。
乾杯
ダニエル
parallel_for_eachが同期vs非同期であるという投稿の2番目の質問に気づきました(申し訳ありませんが、スレッドごとに1つの質問に慣れています;-)「parallel_for_eachがそれなしで「同期的に」動作することを信頼できますか(進行中のコードなし) ?」
その答えは、parallel_for_eachに関する私の投稿にあります: http ://www.danielmoth.com/Blog/parallelforeach-From-Amph-Part-1.aspx
..また、29:20〜33:00に指定したBUILDレコーディングでも http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-802T
一言で言えば、それが同期していると信頼することはできません、それは非同期です。(暗黙的または明示的な)同期ポイントは、並列ループの結果としてGPUからコピーバックされると予想されるデータにアクセスしようとするコードです。
乾杯
ダニエル
マルチスレッド(並行または並列)では、何かを想定することは決して安全ではないため、除外することは決して安全ではないと確信しています。特定の構成によって与えられる特定の保証がありますが、実行しても問題ないと思われるものを導入することによってこれらの保証を破らないように細心の注意を払う必要がありますが、実際には全体を支える多くの複雑さがあります。
まだC++-AMPを使ったことがありませんが、試してみたいと思います。