背景:有关 C++ AMP 概述,请参阅 Daniel Moth最近的 BUILD 演讲。
只有在最后一个引用中,他们才会调用array_view.synchronize()
.
synchronize()
在这些简单的示例中,是否不需要调用?什么时候可以安全排除?我们可以相信没有它的 parallel_for_each 行为“同步”(w/r/t 进行代码)?
如果您想在不通过 array_view 接口的情况下访问数据,请使用 synchronize()。如果您对数据的所有访问都使用 array_view 运算符和函数,则不需要使用 synchronize()。正如 Daniel 所提到的,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 ,因为析构函数调用同步。话虽如此,我没有遵循最佳实践(对不起),即显式调用同步。原因是如果此时抛出任何异常,如果将它们留给析构函数,您将不会观察它们,因此请显式调用同步。
干杯
丹尼尔
刚刚注意到您的帖子中关于 parallel_for_each 是同步与异步的第二个问题(对不起,我习惯于每个线程 1 个问题 ;-) “我们可以相信 parallel_for_each 在没有它的情况下“同步”地表现吗(w/r/t 后续代码) ?”
答案在我关于 parallel_for_each 的帖子中: http ://www.danielmoth.com/Blog/parallelforeach-From-Amph-Part-1.aspx
..以及您在 29:20-33:00 http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-802T指向的 BUILD 录音
简而言之,不,你不能相信它是同步的,它是异步的。(隐式或显式)同步点是任何试图访问由于并行循环而从 GPU 复制回来的数据的代码。
干杯
丹尼尔
我敢打赌,排除是绝对不安全的,因为在多线程(并发或并行)中,假设任何事情都不安全。某些结构可以为您提供某些保证,但是您必须非常小心谨慎,不要通过引入您认为可以做的事情来破坏这些保证,但实际上整个事情有很多复杂性。
还没有花时间使用 C++-AMP,但我倾向于尝试一下。