1

我有以下问题:

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

4

1 回答 1

1

您的 C++ AMP 问题

C++ AMP 支持两种核心数据类型,用于在 GPU 上引用数据

数组表示加速器上的数据。您可以在一个步骤中构建它并用数据填充它,或者稍后构建它并用数据填充它。无论哪种情况,在对其执行了一些计算之后,您几乎肯定会将结果从数组复制回 CPU,以便您可以在应用程序的其他部分中使用它们。

您当然可以仅使用数组编写有用的应用程序,但 C++ AMP 还提供了 array_view,它支持的功能通常比直接使用数组更方便。array_view 在加速器中看起来像一个数组,但它省去了将数据复制到加速器和从加速器复制数据的麻烦。

array_view 和数组之间的关系有点(但不精确)类似于引用和它所引用的对象之间的关系。像引用一样,数组视图必须在创建时进行初始化。同样与引用一样,更改 array_view (最终)更改了创建它的数据。但是,反之则不然:更改创建 array_view 的数据可能不会自动更改 array_view,因此您应该小心处理此类操作。

来自:C++ AMP:加速大规模并行

我不认为你的使用pixels本身就是问题。您不能在 C++ AMP lambda 句点内使用全局范围的变量。没有办法解决这个问题。C++ AMP 代码在具有不同内存空间的设备上执行。

但是,您可以在单独的方法或构造函数中更早地初始化您的arrayarray_view对象,然后将它们传递给完成所有工作的函数。下面的代码按照这些思路做了一些事情。m_frames是指向 (C++ AMP) 对象的指针数组,array这些对象被声明为类的一部分,然后在ConfigureFrameBuffers.

请注意,它使用 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 声明的 min/max 函数(它还定义了在restrict(amp)lambdas 中使用的 min/max)。

#define NOMINMAX

如果您使用 GDI,您也会遇到问题,因为它需要 Windows MIN/MAX 宏。

我将 GIDPlus.h 包装在包含以下内容的包装头中:

#pragma once

#define NOMINMAX
#include <algorithm>
#ifndef max
    #define min std::min
#endif
#ifndef min
    #define max std::max
#endif
#include <gdiplus.h>
#undef max 
#undef min 
于 2014-01-06T06:35:43.670 回答