C ++ amp:传输数据异步并将数据保存在加速器上

时间:2014-08-26 00:12:07

标签: c++ asynchronous hardware-acceleration c++-amp

我有一个非常适合并行处理的常用函数,因此我为初学者调查了C ++放大器。该函数接受三个输入:

  1. 浮点数的向量,它是输入数据
  2. 常数系数的向量,在整个调用中保持不变
  3. 输出向量,其结果写入。
  4. 现在显然,每次调用都必须将#1复制到GPU上。为此,我使用的是堆栈管理的const数组<>,工作正常。

    对于#2,最佳情况是以某种方式将向量保持在GPU内存中,因为它是常量。这是否可以使用放大器?或者每次调用parallel_for_each时都要复制它,类似于#1?

    对于#3,是否可以在GPU上分配缓冲区并将其复制回来,而不是在cpu堆栈上创建一个空缓冲区,复制它,并在结果写入后将其复制回来?

    最后一点,因为parallel_for_each调用本质上是异步的 - 并且将由#3或array_view :: synchronize()的析构函数同步,是否可以保留当前函数(和堆栈空间),做一些其他的东西同时GPU正在处理,然后在稍后“同步”?

    它需要动态分配的array_view以避免在销毁时使用synchronize(),但是当我使用指针而不是堆栈管理的对象时,函数似乎不会编译:

    error C3581: unsupported type in amp restricted code
    pointer or reference is not allowed as pointed to type, array element type or data member type (except reference to concurrency::array/texture)
    

    此外,对于那些在OpenCL等其他架构方面经验丰富的人来说,我会有更好的运气吗?

1 个答案:

答案 0 :(得分:3)

1 - 是的。如果传递const array_view作为输入,则不会将其复制回主机内存。

std::vector<float> cpu_data(20000000, 0.0f);
array_view<const float, 1> cpu_data_view(cpu_data.size(), cpu_data);

2 - 根据您的系数数组的大小,您可以执行以下操作之一;

a - 将其存储在parallel_for_each lambda中的本地数组中。这很方便,但会耗尽(珍贵的)本地内存,所以只有阵列非常小才能实现。

array<float, 1> gpu_data(400);
std::vector<float> cpu_data(gpu_data.extent.size(), 1.0f);
copy(cpu_data.begin(), gpu_data);

在这种情况下,只要lambda捕获它,gpu_data就可用于所有AMP代码。

b - 创建array并在执行任何AMP代码之前将常量数据显式复制到其中。

c - 如果每个帖子多次访问它,请考虑将其加载到tile_static内存中。

3 - 您仍然可以使用array_view来保存输出数据,但在执行discard_data之前调用parallel_for_each将阻止不必要的副本到GPU内存。

std::vector<float> cpu_output_data(20000000, 0.0f);
array_view<float, 1> output_data_view(cpu_output_data.size(), cpu_output_data);
output_data_view.discard_data();

**异步 - **是的,完全可以这样做。您可以将AMP与C ++期货和异步操作结合起来,同时在CPU(或其他GPU)上执行其他工作。请记住,CPU参与控制GPU上的工作安排以及将数据移入和移出GPU。因此,如果您使CPU过载,那么GPU性能可能会受到影响。

WRT到您的编译器错误,如果没有看到代码,很难说出问题所在。完成以下操作是完全可以的:

std::unique_ptr<concurrency::array_view<int, 2>> data_view;

您可能想查看examples covered in the C++ AMP book。它们可以在CodePlex上使用,并涵盖了很多这些场景。