如果我在concurrency::array_view
循环中操作concurrency::parallel_for_each
,我的理解是我可以在循环执行时继续执行CPU上的其他任务:
using namespace Concurrency;
array_view<int> av;
parallel_for_each(extent<1>(number),[=](index<1> idx)
{
// do some intense computations on av
}
// do some stuff on the CPU while we wait
av.synchronize(); // wait for the parallel_for_each loop to finish and copy the data
但是如果我想不等待并行for循环但是开始尽快从GPU 重新开始复制数据。以下是否有效?
using namespace Concurrency;
array_view<int> av;
parallel_for_each(extent<1>(number),[=](index<1> idx)
{
// do some intense computations on av
}
// I know that we won't be waiting to synch when I call this, but will we be waiting here
// until the data is available on the GPU end to START copying?
completion_future waitOnThis = av.synchronize_asynch();
// will this line execute before parallel_for_each has finished processing, or only once it
// has finished processing an the data from "av" has started copying back?
completion_future.wait();
我在The Moth上阅读了这个主题,但在阅读了以下内容之后,我并不是更明智:
请注意,parallel_for_each的执行方式与同步一样 调用代码,但实际上,它是异步的。即一旦 并行调用parallel_for_each并将内核传递给 运行时,some_code_B区域继续立即执行 CPU线程,并行内核由GPU执行 线程。但是,如果您尝试访问(array或array_view)数据 您在some_code_B区域中的lambda中捕获的代码 将阻止,直到结果可用。因此是正确的 声明:parallel_for_each是as-if同步的 可见的副作用,但实际上是异步的。
答案 0 :(得分:2)
我不喜欢这个解释的方式。考虑它的一个更好的方法是parallel_for_each
队列对GPU起作用,因此它几乎立即返回。在排队工作完成之前,您的CPU端代码可以通过多种方式阻止,例如,显式调用synchronize
,或访问array_view
中使用的parallel_for_each
个实例之一的数据}
using namespace concurrency;
array_view<int> av;
parallel_for_each(extent<1>(number),[=](index<1> idx)
{
// Queue (or schedule if you like) some intense computations on av
}
主机代码现在可以执行。 AMP计算可能已启动,也可能未启动。如果此处的代码访问av
,则它将阻塞,直到GPU上的工作完成并且av
中的数据已写入并且可以与主机内存同步。
这是一个未来,因此它也是一项计划任务。不保证
在任何特定点执行。如果它被调度,那么它将阻止它运行的线程,直到av
与主机内存正确同步(如上所述)。
completion_future waitOnThis = av.synchronize_asynch();
此处可以执行更多主机代码。如果主机代码访问av
,则它将阻塞,直到parallel_for_each
完成(如上所述)。在某些时候,运行时将执行将来并阻塞,直到av
与主机内存同步。如果它是可写的并且已被更改,那么它将被复制回主机存储器。
completion_future.wait();
对wait
的调用将阻止,直到将来完成(在调用wait
之前,无法保证实际执行了任何操作)。此时,您可以确保GPU计算完成,并且可以在CPU上访问av
。
说过所有添加waitOnThis
未来的事情似乎过于复杂化了。
array_view<int> av;
parallel_for_each(extent<1>(number),[=](index<1> idx)
{
// do some intense computations on av on the GPU
}
// do some independent CPU computation here.
av.synchronize();
// do some computation on the CPU that relies on av here.
MSDN文档在这个主题上不是很好。以下blog post更好。在同一博客上的异步API上还有一些其他帖子。