何时在C ++ AMP中调用“synchronize()”不是必需的?

时间:2011-09-22 06:24:01

标签: c++ c++-amp

背景:有关C ++ AMP的概述,请参阅Daniel Moth的recent BUILD talk

完成初步演练herehereherehere

只有在最后一次引用中,他们才会调用array_view.synchronize()

在这些简单的示例中,是否需要调用synchronize()?什么时候可以安全排除?我们能否相信parallel_for_each在没有它的情况下“同步”行事(w / r / t正在进行的代码)?

4 个答案:

答案 0 :(得分:10)

如果要访问数据而不使用通过array_view接口,请使用synchronize()。如果您对数据的所有访问都使用array_view运算符和函数,则不需要使用synchronize()。正如Daniel所提到的,array_view的析构函数也强制同步,在这种情况下调用synchronize()会更好,这样你就可以得到任何可能抛出的异常。

同步函数强制对调用上下文中的缓冲区进行更新 - 也就是说,如果您在GPU上写入数据然后在CPU代码中调用synchronize,那么更新的值将被复制到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

答案 1 :(得分:4)

我显示的简单示例不需要

my_array_view_instance.synchronize,因为析构函数调用synchronize。话虽如此,我并没有遵循最佳实践(抱歉),这是明确调用同步。原因是如果在那一点抛出任何异常,如果你把它们留给析构函数你就不会观察它们,所以请明确地调用synchronize。

干杯

丹尼尔

答案 2 :(得分:3)

刚刚注意到你帖子中关于parallel_for_each同步vs asyncrhonous的第二个问题(对不起,我习惯了每个帖子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指出的BUILD录音 http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-802T

简而言之,不,你不能相信它是同步的,它是异常的。 (隐式或显式)同步点是尝试访问由于并行循环而期望从GPU复制回来的数据的任何代码。

干杯

丹尼尔

答案 3 :(得分:1)

我认为排除它永远不会安全,因为在多线程(并发或并行)中,假设任何事情都是不安全的。某些结构给你提供了某些保证但是,你必须非常小心和细致,不要通过引入你认为可以做的事来打破这些保证,但实际上有很多复杂性支撑着整个事情。

还没有花时间使用C ++ - AMP,但我倾向于尝试一下。