在C ++ Amp中使用指针

时间:2014-01-05 17:05:36

标签: c++ multithreading parallel-processing gpgpu c++-amp

我遇到了以下问题:

我有一个执行非常基本操作的代码。我传递一个指向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。

1 个答案:

答案 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代码正在具有不同内存空间的设备上执行。

但是,您可以先在单独的方法或构造函数中初始化arrayarray_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