Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中并行的若干算术运算+;放大器_C++_Multithreading_Parallel Processing_Gpgpu_C++ Amp - Fatal编程技术网

C++ 在C+中并行的若干算术运算+;放大器

C++ 在C+中并行的若干算术运算+;放大器,c++,multithreading,parallel-processing,gpgpu,c++-amp,C++,Multithreading,Parallel Processing,Gpgpu,C++ Amp,我正在尝试使用C++Amp并行化卷积滤波器。我希望以下功能开始工作(我不知道如何正确执行): float*pixel_color[]=新浮点[16]; 并发性::数组\查看像素(4,4,像素\数组),点击(4,4,myTap4Kernel\数组); 并发性::数组_视图像素(16,像素_颜色);//我不知道在这里使用哪种数据结构 每个单元的平行单元( pixels.extent,[=](并发::索引idx)限制(amp) { int row=idx[0]; int col=idx[1]; 像素(

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

float*pixel_color[]=新浮点[16];
并发性::数组\查看像素(4,4,像素\数组),点击(4,4,myTap4Kernel\数组);
并发性::数组_视图像素(16,像素_颜色);//我不知道在这里使用哪种数据结构
每个单元的平行单元(
pixels.extent,[=](并发::索引idx)限制(amp)
{
int row=idx[0];
int col=idx[1];
像素(行,列)=点击(行,列)*像素(行,列);
像素[0]+=像素(行、列);
});
像素_颜色。同步();
(j,i)处的像素=像素颜色
}

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

concurrency::array_view<float, 2> pixels(4, 4, pixel_array), taps(4, 4, myTap4Kernel_array); 
concurrency::array\u查看像素(4,4,像素数组),点击(4,4,myTap4Kernel\u数组);

在方法之外(例如在头文件中),并在costructor或其他函数中初始化它(因为这是一个瓶颈,需要在CPU和GPU之间复制数据)。有人知道怎么做吗

您的做法并不正确,但在GPU上对阵列进行就地操作很棘手,因为您无法保证不同元素的更新顺序

这里有一个非常类似的例子。
applycolorsImplicifiedHelper
方法包含一个AMP限制的并行\u,用于为2D数组中的每个索引调用
SimplifiedIndextiled
SimplifiedIndextiled
根据
srcFrame
中相应像素周围的像素值,为
destFrame
中的每个像素计算一个新值。这解决了代码中存在的竞争条件问题

此代码来自。Cartoonizer案例研究包括了几种C++处理中使用的图像处理问题的例子;阵列、纹理、平铺/未平铺和多GPU。本文详细讨论了实现

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);
}

我不清楚你想在这里做什么。通常,你不会编写一个只处理4x4数据数组的C++内核。我假设这是一个计算每个像素周围4x4卷积掩模结果的函数?您当前的代码无法工作,因为您在GPU上运行的16个线程中的每个线程都试图写入像素[0]。没错,我想计算每个像素周围4x4掩码的结果。我的想法是让每个线程计算16个像素中每个像素的颜色,然后将所有结果相加,以接收像素的结果颜色。我想对图像中的每个像素都做同样的操作。我正在对图像进行操作,所以我提到的纹理结构可能会对我有所帮助,但是我还不知道如何操作。我更喜欢使用浮点而不是整数,因为它提供了更好的资源,而且我正在单色图像上操作。如果你只需要一个浮点来表示每个像素的灰度,那么你几乎可以用浮点替换ArgbPackedPixel。这回答了你的问题吗?实际上我已经实现了不需要的操作按特定顺序进行。我的代码计算像素的新值,然后将该值存储在输出缓冲区中。如果你愿意,我可以粘贴代码。
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);
}
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;
}