我遇到了以下问题:
我有一个执行非常基本操作的代码。我传递一个指向concurrency :: array_view的指针,因为我想更早地存储这些值以避免使用多线程的函数中的瓶颈。问题是以下构造不会编译:
parallel_for_each((*pixels).extent, [=](concurrency::index<2> idx) restrict(amp)
{
int row=idx[0];
int col=idx[1];
(*pixels)(row, col) = (*pixels)(row, col) * (*taps)(row, col); //this is the problematic place
});
有人知道如何解决这个案子吗?我真的需要在运行方法之前准备数据所以这是这样做的唯一方法,因为我无法花时间在RAM和加速器的内存之间复制数据。
//编辑:
解决了头文件的一些问题后,我留下了以下问题:
parallel_for_each((*pixels).extent, [=](concurrency::index<2> idx) restrict(amp)
{
int row=idx[0];
int col=idx[1];
});
上面的代码不起作用(它给出了例外)。有没有任何方法来提前准备数据,例如类的构造函数可以处理它只复制一次吗?我真的需要在我的头文件中有一个指向array_view的指针,并在构造函数中初始化它,如下所示:
在cci_subset.h中:
concurrency::array_view<float, 2> *pixels, *taps;
并在subset.cpp中:
concurrency::array_view<float, 2> pixels(4, 4, pixel_array);
...
concurrency::array_view<float, 2> taps(4, 4, myTap4Kernel_array);
//编辑2:
我发现parallel_for_each的参数只能通过值传递。这就是为什么我仍在寻找一种方法,在初始化类或将一些参数(即图像数据)传递给类时,将值从CPU复制到GPU。
答案 0 :(得分:1)
您的C ++ AMP问题
C ++ AMP支持两种核心数据类型,用于引用GPU上的数据
数组表示加速器上的数据。你可以构建它 在一个步骤中填充数据或构建它并填充它 数据以后。在任何一种情况下,经过一些计算后 在它上面执行,你几乎肯定会复制一个结果 数组返回到CPU,以便您可以在其他部分使用它们 你的申请。
你当然可以只使用数组编写有用的应用程序, 但是C ++ AMP还提供了array_view,它支持功能 这通常比直接使用数组更方便。 array_view看起来像加速器的数组,但它可以节省你的时间 安排从中复制数据的麻烦 加速器。
array_view和数组之间的关系是 有点(但不完全)像参考和之间的那样 它指的是对象。与引用一样,必须初始化数组视图 什么时候创建它们。也作为参考,改变了 array_view更改(最终)创建它的数据。然而, 相反的情况并非如此:更改数据 array_view创建可能不会自动更改array_view, 所以你应该小心处理这些操作。
来自:C++ AMP: Accelerated Massive Parallelism
我不认为您使用pixels
本身就是问题。您不能在C ++ AMP lambda中使用全局范围的变量。没有办法解决这个问题。 C ++ AMP代码正在具有不同内存空间的设备上执行。
但是,您可以先在单独的方法或构造函数中初始化array
或array_view
对象,然后将它们传递给执行所有工作的函数。以下代码沿着这些方向做了一些事情。 m_frames
是一个指向(C ++ AMP)array
对象的指针数组,这些对象被声明为类的pare,然后在ConfigureFrameBuffers
中初始化。
请注意,它使用STL智能指针,我强烈推荐使用STL智能指针。
class FrameProcessorAmpBase
{
private:
std::shared_ptr<array<float, 2> m_frame;
public:
FrameProcessorAmpBase()
{
}
void ConfigureFrameBuffers(int width, int height)
{
m_frame = std::make_shared<array<float, 2>>(height, width));
}
您的最小/最大标头问题
这可能是因为你包含了windef.h,或者是依赖于它的东西。混合STL和Windows标头时,这是一个已知问题。 “修复”它的方法是在任何其他包含之前在文件顶部定义NOMINMAX
,然后使用STL或AMP声明的最小/最大函数(它还定义最小/最大值以便在{{中使用) 1}} lambdas)。
restrict(amp)
如果你正在使用GDI,那么你也会遇到问题,因为它需要Windows MIN / MAX宏。
我将GIDPlus.h包装在一个包含以下内容的包装器头中:
#define NOMINMAX