何时调用“synchronize()”在 C++ 中不需要安普?

发布于 2024-12-06 07:01:25 字数 729 浏览 2 评论 0原文

背景:有关 C++ AMP 概述,请参阅 Daniel Moth 的 最近的构建谈话

此处,此处此处,以及 此处

仅在最后一个引用中,他们才会调用 array_view.synchronize()。

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

Background: For a C++ AMP overview, see Daniel Moth's recent BUILD talk.

Going through the initial walk-throughs here, here, here, and here.

Only in that last reference do they make a call to array_view.synchronize().

In these simple examples, is a call to synchronize() not needed? When is it safe to exclude? Can we trust parallel_for_each to behave "synchronously" without it (w/r/t the proceeding code)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

追风人 2024-12-13 07:01:25

当您想要通过 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

Use synchronize() when you want to access the data without going through the array_view interface. If all of your access to the data uses array_view operators and functions, you don't need to use synchronize(). As Daniel mentioned, the destructor of an array_view forces a synchronize as well, and it's better to call synchronize() in that case so you can get any exceptions that might be thrown.

The synchronize function forces an update to the buffer within the calling context -- that is if you write data on the GPU and then call synchronize in CPU code, at that point the updated values are copied to CPU memory.

This seems obvious from the name, but I mention it because other array_view operations can cause a 'synchronize' as well. C++ AMP array_view tries it best to make copying between the CPU and GPU memory implict -- any operation which reads data through the array view interface will cause a copy as well.

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
请你别敷衍 2024-12-13 07:01:25

我展示的简单示例不需要 my_array_view_instance.synchronize,因为析构函数调用 Synchronize。话虽如此,我没有遵循最佳实践(抱歉),即显式调用同步。原因是,如果此时抛出任何异常,如果将它们留给析构函数,您将不会观察到它们,因此请显式调用同步。

干杯

丹尼尔

my_array_view_instance.synchronize is not required for the simple examples I showed because the destructor calls synchronize. Having said that, I am not following best practice (sorry), which is to explicitly call synchronize. The reason is that if any exceptions are thrown at that point, you would not observe them if you left them up to the destructor, so please call synchronize explicitly.

Cheers

Daniel

怼怹恏 2024-12-13 07:01:25

刚刚注意到您帖子中关于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 指出的 BUILD 记录中
http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-802T

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

干杯

丹尼尔

Just noticed the second question in your post about parallel_for_each being synchronous vs asyncrhonous (sorry, I am used to 1 question per thread ;-)
"Can we trust parallel_for_each to behave "synchronously" without it (w/r/t the proceeding code)?"

The answer to that is on my post about parallel_for_each:
http://www.danielmoth.com/Blog/parallelforeach-From-Amph-Part-1.aspx

..and also in the BUILD recording you pointed to from 29:20-33:00
http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-802T

In a nutshell, no you cannot trust it to be synchronous, it is asyncrhonous. The (implicit or explicit) synchronization point is any code that tries to access the data that is expected to be copied back from the GPU as a result of your parallel loop.

Cheers

Daniel

往日 2024-12-13 07:01:25

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

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

I'm betting that it's never safe to exclude because in a multi-threaded (concurrent or parallel) it's never safe to assume anything. There are certain guarantees which certain constructs give you but, you have to super careful and meticulous not to break these guarantees by introducing something which you think is fine to do but when in reality there's a lot of complexity underpinning the whole thing.

Haven't spent any time with C++-AMP yet but I'm inclined to try it out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文