gpt4 book ai didi

c++ - 在 C++Amp 中并行的几个算术运算

转载 作者:太空宇宙 更新时间:2023-11-04 11:42:16 25 4
gpt4 key购买 nike

我正在尝试使用 C++Amp 并行化卷积滤波器。我希望以下功能开始工作(我不知道如何正确执行):

float* pixel_color[] = new float [16]; 

concurrency::array_view<float, 2> pixels(4, 4, pixel_array), taps(4, 4, myTap4Kernel_array);
concurrency::array_view<float, 1> pixel(16, pixel_color); // I don't know which data structure to use here

parallel_for_each(
pixels.extent, [=](concurrency::index<2> idx) restrict(amp)
{
int row=idx[0];
int col=idx[1];

pixels(row, col) = taps(row, col) * pixels(row, col);
pixel[0] += pixels(row, col);
});
pixel_color.synchronize();

pixels_.at<Pixel>(j, i) = pixel_color

}

主要问题是我不知道如何正确使用像素结构(这里要使用哪个并发数据结构,因为我不需要所有 16 个元素)。而且我不知道我是否可以通过这种方式安全地添加值。下面的代码不起作用,它没有向 pixel[0] 添加适当的值。我也想定义

concurrency::array_view<float, 2> pixels(4, 4, pixel_array), taps(4, 4, myTap4Kernel_array); 

在方法之外(例如在头文件中)并在构造函数或其他函数中对其进行初始化(因为这是一个瓶颈,需要花费大量时间在 CPU 和 GPU 之间复制数据)。有人知道怎么做这个吗?

最佳答案

您的方向不对,但在 GPU 上对数组进行就地操作很棘手,因为您无法保证不同元素的更新顺序。

这是一个非常相似的例子。 ApplyColorSimplifierTiledHelper 方法包含一个受 AMP 限制的 parallel_for_each,它为二维数组中的每个索引调用 SimplifyIndexTiledSimplifyIndexTiled 根据 srcFrame 中相应像素周围的像素值计算 destFrame 中每个像素的新值。这解决了代码中存在的竞争条件问题。

此代码来自Codeplex site for the C++ AMP book . Cartoonizer 案例研究包括几个使用 C++ AMP 实现的此类图像处理问题的示例;数组、纹理、平铺/未平铺和多 GPU。 C++ AMP book详细讨论了实现。

void ApplyColorSimplifierTiledHelper(const array<ArgbPackedPixel, 2>& srcFrame,
array<ArgbPackedPixel, 2>& destFrame, UINT neighborWindow)
{
const float_3 W(ImageUtils::W);

assert(neighborWindow <= FrameProcessorAmp::MaxNeighborWindow);

tiled_extent<FrameProcessorAmp::TileSize, FrameProcessorAmp::TileSize>
computeDomain = GetTiledExtent(srcFrame.extent);
parallel_for_each(computeDomain, [=, &srcFrame, &destFrame]
(tiled_index<FrameProcessorAmp::TileSize, FrameProcessorAmp::TileSize> idx)
restrict(amp)
{
SimplifyIndexTiled(srcFrame, destFrame, idx, neighborWindow, W);
});
}

void SimplifyIndex(const array<ArgbPackedPixel, 2>& srcFrame, array<ArgbPackedPixel,
2>& destFrame, index<2> idx,
UINT neighborWindow, const float_3& W) restrict(amp)
{
const int shift = neighborWindow / 2;
float sum = 0;
float_3 partialSum;
const float standardDeviation = 0.025f;
const float k = -0.5f / (standardDeviation * standardDeviation);

const int idxY = idx[0] + shift; // Corrected index for border offset.
const int idxX = idx[1] + shift;
const int y_start = idxY - shift;
const int y_end = idxY + shift;
const int x_start = idxX - shift;
const int x_end = idxX + shift;

RgbPixel orgClr = UnpackPixel(srcFrame(idxY, idxX));

for (int y = y_start; y <= y_end; ++y)
for (int x = x_start; x <= x_end; ++x)
{
if (x != idxX || y != idxY) // don't apply filter to the requested index, only to the neighbors
{
RgbPixel clr = UnpackPixel(srcFrame(y, x));
float distance = ImageUtils::GetDistance(orgClr, clr, W);
float value = concurrency::fast_math::pow(float(M_E), k * distance * distance);
sum += value;
partialSum.r += clr.r * value;
partialSum.g += clr.g * value;
partialSum.b += clr.b * value;
}
}

RgbPixel newClr;
newClr.r = static_cast<UINT>(clamp(partialSum.r / sum, 0.0f, 255.0f));
newClr.g = static_cast<UINT>(clamp(partialSum.g / sum, 0.0f, 255.0f));
newClr.b = static_cast<UINT>(clamp(partialSum.b / sum, 0.0f, 255.0f));
destFrame(idxY, idxX) = PackPixel(newClr);
}

该代码使用 ArgbPackedPixel,这是一种将 8 位 RGB 值打包到 unsigned long 中的机制,因为 C++ AMP 不支持 char。如果您的问题小到足以放入纹理,那么您可能希望使用它而不是数组,因为打包/解包是在 GPU 上的硬件中实现的,因此实际上是“免费的”,在这里您必须为此付费额外的计算。 CodePlex 上也有此实现的示例。

typedef unsigned long ArgbPackedPixel;

struct RgbPixel
{
unsigned int r;
unsigned int g;
unsigned int b;
};

const int fixedAlpha = 0xFF;

inline ArgbPackedPixel PackPixel(const RgbPixel& rgb) restrict(amp)
{
return (rgb.b | (rgb.g << 8) | (rgb.r << 16) | (fixedAlpha << 24));
}


inline RgbPixel UnpackPixel(const ArgbPackedPixel& packedArgb) restrict(amp)
{
RgbPixel rgb;
rgb.b = packedArgb & 0xFF;
rgb.g = (packedArgb & 0xFF00) >> 8;
rgb.r = (packedArgb & 0xFF0000) >> 16;
return rgb;
}

关于c++ - 在 C++Amp 中并行的几个算术运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20927900/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com