Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.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
Image processing 使用atomicAdd平均CUDA上的图像会产生不一致的结果_Image Processing_Graphics_Parallel Processing_Cuda_Computer Vision - Fatal编程技术网

Image processing 使用atomicAdd平均CUDA上的图像会产生不一致的结果

Image processing 使用atomicAdd平均CUDA上的图像会产生不一致的结果,image-processing,graphics,parallel-processing,cuda,computer-vision,Image Processing,Graphics,Parallel Processing,Cuda,Computer Vision,我将平均图像的强度作为一个更大问题的简单测试用例。但每次运行时,得到的结果都略有不同。相反,如果我在CPU上连续运行相同的算法,结果是静态的。让我们看看GPU上的代码 //util.cu __global__ void avgImageDevice(float3 *avg, float3 *d_colorImageRGB, unsigned int width, unsigned int height) { const unsigned int x = blockIdx.x*blockD

我将平均图像的强度作为一个更大问题的简单测试用例。但每次运行时,得到的结果都略有不同。相反,如果我在CPU上连续运行相同的算法,结果是静态的。让我们看看GPU上的代码

//util.cu
__global__ void avgImageDevice(float3 *avg, float3 *d_colorImageRGB, unsigned int width, unsigned int height)
{
    const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
    const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
    if (x >= width || y >= height) return;

    atomicAdd(&avg->x, d_colorImageRGB[y*width + x].x);
    atomicAdd(&avg->y, d_colorImageRGB[y*width + x].y);
    atomicAdd(&avg->z, d_colorImageRGB[y*width + x].z);
}

extern "C" void avgImage(float3 *avg, float3 *d_colorImageRGB, unsigned int width, unsigned int height)
{
    const int T_PER_BLOCK = 16;
    const dim3 blockSize((width + T_PER_BLOCK - 1) / T_PER_BLOCK, (height + T_PER_BLOCK - 1) / T_PER_BLOCK);
    const dim3 gridSize(T_PER_BLOCK, T_PER_BLOCK);

    avgImageDevice << <blockSize, gridSize >> >(avg, d_colorImageRGB, width, height);
}

我有GTX960、CUDA6.5和Windows7。这是一个数据竞争问题吗?据我所知,
atomicAdd
没有报告全局内存有任何问题。

结果可能取决于线程的调度顺序。实际上,根据图像大小、组件中的值,结果平均值可能会因运行而略有不同,尽管所有值都是正确的。如果num不同于一个运行到另一个运行,则代码的其他部分很可能存在问题。如果num相同,则所有结果都符合IEEE-754标准

结果可能取决于线程的调度顺序。实际上,根据图像大小、组件中的值,结果平均值可能会因运行而略有不同,尽管所有值都是正确的。如果num不同于一个运行到另一个运行,则代码的其他部分很可能存在问题。如果num相同,则所有结果都符合IEEE-754标准

这不是一场数据竞赛

浮点加法是可交换的:

a + b == b + a
但它是非关联的;有a、b、c,以便:

(a + b) + c != a + (b + c)
单个添加的不同顺序(特别是它们的关联方式)将产生不同的结果。

这不是数据竞争

浮点加法是可交换的:

a + b == b + a
但它是非关联的;有a、b、c,以便:

(a + b) + c != a + (b + c)

单个加法的不同顺序(特别是它们的关联方式)将产生不同的结果。

您是否确实初始化了传递的值并以原子方式递增?是的。我确保了我正在初始化所有的东西。那么,当你还没有发布一个?我只是想猜测一下?相应地修改了。您是否验证了程序集以确保您的cpu操作在fp32而不是fp64中?您是否确实初始化了您传递的值并以原子方式递增?是的。我确保了我正在初始化所有的东西。那么,当你还没有发布一个?我只是猜一下?相应地修改了。你们验证了程序集以确保你们的cpu操作在fp32而不是fp64中吗?这实际上是有道理的。将平均强度视为一棵树从下到上的节点总和,然后在GPU中,这棵树在每次迭代中看起来都不同。因为每个线程都在不同的时间范围内运行。这实际上是有意义的。将平均强度视为一棵树从下到上的节点总和,然后在GPU中,这棵树在每次迭代中看起来都不同。因为每个线程都在不同的时间范围内运行。