Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/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
C++ CUDA在执行期间组合与线程无关的(??)变量_C++_Visual Studio 2008_Cuda - Fatal编程技术网

C++ CUDA在执行期间组合与线程无关的(??)变量

C++ CUDA在执行期间组合与线程无关的(??)变量,c++,visual-studio-2008,cuda,C++,Visual Studio 2008,Cuda,伙计们,如果标题让人困惑,我道歉。我想得又长又难,想不出一句话来表达这个问题的正确方法。这里有更多的细节。我正在做一个基本的图像减法,其中第二个图像已经被修改,我需要找到对图像进行了多少更改的比率。为此,我使用了以下代码。两幅图像均为128x1024 for(int i = 0; i < 128; i++) { for(int j = 0; j < 1024; j++) { den++; diff[i * 1024 + j] = ori

伙计们,如果标题让人困惑,我道歉。我想得又长又难,想不出一句话来表达这个问题的正确方法。这里有更多的细节。我正在做一个基本的图像减法,其中第二个图像已经被修改,我需要找到对图像进行了多少更改的比率。为此,我使用了以下代码。两幅图像均为128x1024

for(int i = 0; i < 128; i++)
{
    for(int j = 0; j < 1024; j++)
    {
        den++;
        diff[i * 1024 + j] = orig[i * 1024 + j] - modified[i * 1024 + j];
        if(diff[i * 1024 + j] < error)
        {
            num++;
        }
    }
}
ratio = num/den;
for(int i=0;i<128;i++)
{
对于(int j=0;j<1024;j++)
{
den++;
diff[i*1024+j]=orig[i*1024+j]-修改的[i*1024+j];
如果(差异[i*1024+j]<错误)
{
num++;
}
}
}
比率=num/den;
上面的代码在CPU上运行良好,但我想在CUDA上尝试这样做。为此,我可以设置CUDA来执行图像的基本减法(下面的代码),但我不知道如何执行条件if语句来获得我的比率

__global__ void calcRatio(float *orig, float *modified, int size, float *result)
{
    int index = threadIdx.x + blockIdx.x * blockDim.x;
    if(index < size)
        result[index] = orig[index] - modified[index];
}
\uuuu全局\uuuuu无效计算(浮点*原始,浮点*修改,整数大小,浮点*结果)
{
int index=threadIdx.x+blockIdx.x*blockDim.x;
如果(索引<大小)
结果[索引]=原始[索引]-修改[索引];
}
因此,到目前为止,它还可以工作,但我不知道如何对每个线程中的num和den计数器进行并行化,以计算所有线程执行结束时的比率。对我来说,感觉num和den顾问独立于线程,因为每次我尝试使用它们时,它们似乎只增加一次

任何帮助都将不胜感激,因为我刚刚开始在CUDA学习,我在网上看到的每一个例子似乎都不适用于我需要做的事情

编辑:修复了我的幼稚代码。忘记在代码中键入一个主要条件。这是漫长的一天。

for(int i = 0; i < 128; i++)
{
    for(int j = 0; j < 1024; j++)
    {
        if(modified[i * 1024 + j] < 400.0)  //400.0 threshold value to ignore noise
        {
            den++;  
            diff[i * 1024 + j] = orig[i * 1024 + j] - modified[i * 1024 + j];
            if(diff[i * 1024 + j] < error)
            {
                num++;
            }
        }
    }
}
ratio = num/den;
for(int i=0;i<128;i++)
{
对于(int j=0;j<1024;j++)
{
if(修改[i*1024+j]<400.0)//400.0阈值以忽略噪声
{
den++;
diff[i*1024+j]=orig[i*1024+j]-修改的[i*1024+j];
如果(差异[i*1024+j]<错误)
{
num++;
}
}
}
}
比率=num/den;

分母非常简单,因为它只是大小

分子更麻烦,因为它对于给定线程的值取决于之前的所有值。你必须连续地做这个操作

你要找的东西可能是原子加法。不过速度很慢

我想你会发现这个问题很重要。您的num基本上是全局数据。


或者,您可以将错误检查的结果转储到数组中。然后,计算结果可以并行化。这可能有点棘手,但我认为类似的东西会放大:

分母非常简单,因为它只是大小

分子更麻烦,因为它对于给定线程的值取决于之前的所有值。你必须连续地做这个操作

你要找的东西可能是原子加法。不过速度很慢

我想你会发现这个问题很重要。您的num基本上是全局数据。


或者,您可以将错误检查的结果转储到数组中。然后,计算结果可以并行化。这可能有点棘手,但我认为类似这样的操作会放大:

在所有线程之间执行全局求和所需的操作称为“并行缩减”。虽然可以使用原子操作来实现这一点,但我不推荐这样做。CUDA SDK中有一个还原内核和一篇讨论该技术的非常好的文章,值得一读

如果我编写代码来实现您想要的功能,它可能会如下所示:

template <int blocksize>
__global__ void calcRatio(float *orig, float *modified, int size, float *result, 
                            int *count, const float error)
{
    __shared__ volatile float buff[blocksize];

    int index = threadIdx.x + blockIdx.x * blockDim.x;
    int stride = blockDim.x * gridDim.x;

    int count = 0;
    for(int i=index; i<n; i+=stride) {
        val = orig[index] - modified[index];
        count += (val < error);
        result[index] = val;
    }

    buff[threadIdx.x] = count;
    __syncthreads();


    // Parallel reduction in shared memory using 1 warp
    if (threadId.x < warpSize) {

        for(int i=threadIdx.x + warpSize; i<blocksize; i+= warpSize) {
            buff[threadIdx.x] += buff[i];

        if (threadIdx.x < 16) buff[threadIdx.x] +=buff[threadIdx.x + 16];
        if (threadIdx.x < 8)  buff[threadIdx.x] +=buff[threadIdx.x + 8];
        if (threadIdx.x < 4)  buff[threadIdx.x] +=buff[threadIdx.x + 4];
        if (threadIdx.x < 2)  buff[threadIdx.x] +=buff[threadIdx.x + 2];
        if (threadIdx.x == 0) count[blockIdx.x] = buff[0] + buff[1];
    }
}
模板
__全局无效计算(浮点*原始,浮点*修改,整型大小,浮点*结果,
整数*计数,常数浮点错误)
{
__共享_uuuuuuuuuuuuvolatile float buff[块大小];
int index=threadIdx.x+blockIdx.x*blockDim.x;
int stride=blockDim.x*gridDim.x;
整数计数=0;

对于(int i=index;i在所有线程之间执行全局求和所需的操作称为“并行缩减”。虽然可以使用原子操作来完成此操作,但我不推荐使用此操作。CUDA SDK中有一个缩减内核和一篇讨论此技术的非常好的文章,值得一读

如果我编写代码来实现您想要的功能,它可能会如下所示:

template <int blocksize>
__global__ void calcRatio(float *orig, float *modified, int size, float *result, 
                            int *count, const float error)
{
    __shared__ volatile float buff[blocksize];

    int index = threadIdx.x + blockIdx.x * blockDim.x;
    int stride = blockDim.x * gridDim.x;

    int count = 0;
    for(int i=index; i<n; i+=stride) {
        val = orig[index] - modified[index];
        count += (val < error);
        result[index] = val;
    }

    buff[threadIdx.x] = count;
    __syncthreads();


    // Parallel reduction in shared memory using 1 warp
    if (threadId.x < warpSize) {

        for(int i=threadIdx.x + warpSize; i<blocksize; i+= warpSize) {
            buff[threadIdx.x] += buff[i];

        if (threadIdx.x < 16) buff[threadIdx.x] +=buff[threadIdx.x + 16];
        if (threadIdx.x < 8)  buff[threadIdx.x] +=buff[threadIdx.x + 8];
        if (threadIdx.x < 4)  buff[threadIdx.x] +=buff[threadIdx.x + 4];
        if (threadIdx.x < 2)  buff[threadIdx.x] +=buff[threadIdx.x + 2];
        if (threadIdx.x == 0) count[blockIdx.x] = buff[0] + buff[1];
    }
}
模板
__全局无效计算(浮点*原始,浮点*修改,整型大小,浮点*结果,
整数*计数,常数浮点错误)
{
__共享_uuuuuuuuuuuuvolatile float buff[块大小];
int index=threadIdx.x+blockIdx.x*blockDim.x;
int stride=blockDim.x*gridDim.x;
整数计数=0;

对于(int i=index;iThanks Talonmes。但是我刚刚意识到我在键入代码时犯了一个巨大的错误。我在漫长的一天之后从内存中键入了这个,所以忘记了一个主要部分。编辑了我上面的文章。这对代码几乎没有什么影响。你添加的条件进入了我发布的内核的第一节的循环中。Ooooo。这大概是当时我在想…但表达得更清楚了。你知道这个操作的名称。这在将来可能会很有用。谢谢Talonmes。但我刚刚意识到我在键入代码时犯了一个巨大的错误。我在漫长的一天之后从内存中键入了这个,所以忘记了一个主要部分。编辑了我上面的帖子。这对代码几乎没有任何影响。您添加的条件在我发布的内核的第一节的循环中。Ooooo。这大致是我所想的…但表达得更清楚。而且您知道此操作的名称。这在将来可能会很有用。