我有一个非常适合并行处理的常用函数,因此我为初学者调查了C ++放大器。该函数接受三个输入:
现在显然,每次调用都必须将#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等其他架构方面经验丰富的人来说,我会有更好的运气吗?
答案 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上使用,并涵盖了很多这些场景。