将array_view.synchronize_asynch等待parallel_for_each完成?

时间:2013-11-07 07:46:44

标签: c++ c++-amp

如果我在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同步的   可见的副作用,但实际上是异步的。

1 个答案:

答案 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上还有一些其他帖子。