CUDA内核-嵌套for循环

CUDA内核-嵌套for循环,cuda,Cuda,你好 我正试图编写一个CUDA内核来执行以下代码 for (n = 0; n < (total-1); n++) { a = values[n]; for ( i = n+1; i < total ; i++) { b = values[i] - a; c = b*b; if( c < 10) newvalues[i] = c; } } for(n=0;n

你好 我正试图编写一个CUDA内核来执行以下代码

for (n = 0; n < (total-1); n++)
{
  a = values[n];

  for ( i = n+1; i < total ; i++)
  {
    b = values[i] - a;
    c = b*b;

    if( c < 10)
        newvalues[i] = c;
    }
}
for(n=0;n<(总计-1);n++)
{
a=数值[n];
对于(i=n+1;i
这就是我目前所拥有的,但它似乎没有给出正确的结果?有人知道我做错了什么吗。干杯

__global__ void calc(int total, float *values, float *newvalues){

float a,b,c;

int idx = blockIdx.x * blockDim.x + threadIdx.x;

for (int n = idx; n < (total-1); n += blockDim.x*gridDim.x){
    a = values[n];

    for(int i = n+1; i < total; i++){
        b = values[i] - a;
        c = b*b;

    if( c < 10)
        newvalues[i] = c;

    }
}
\uuuu全局\uuuuu无效计算(整数合计、浮点*值、浮点*新值){
浮子a、b、c;
int idx=blockIdx.x*blockDim.x+threadIdx.x;
对于(int n=idx;n<(总计-1);n+=blockDim.x*gridDim.x){
a=数值[n];
对于(int i=n+1;i
我可能会大错特错,但是
n
签入

for (int n = idx; n < (total-1); n += blockDim.x*gridDim.x)
for(int n=idx;n<(total-1);n+=blockDim.x*gridDim.x)

似乎与原始版本不同。

为什么不删除outter循环,并使用此循环所需的线程数启动内核?有一个依赖于您的blockId的循环有点奇怪。通常,您会尝试避免这些循环。
其次,在我看来,
newvalues[i]
可以被不同的线程覆盖。

在2D中意识到这个问题,并使用2D线程块启动内核。x和y维度中的线程总数将等于total。内核代码应该如下所示:

__global__ void calc(float *values, float *newvalues, int total){


float a,b,c;

int n= blockIdy.y * blockDim.y + threadIdx.y;
int i= blockIdx.x * blockDim.x + threadIdx.x;

  if (n>=total || i>=total)
        return;

a = values[n];
b = values[i] - a;
c = b*b;
 if( c < 10)
        newvalues[i] = c;  

// I don't know your problem statement but i think it should be like: newvalues[n*total+i] = c;  


}

(i=n+1;pp中的
p
是什么?打字错误。对不起,我不太清楚该怎么做。你的意思是用(total-1)线程启动外循环吗?我想你是对的,
newvalues[i]
可以被覆盖。如果我将代码更改为
newvalues[i]怎么办+=c
,这会将每个线程的贡献相加吗?问题会小得多,但仍然存在问题。想象一下以下场景:线程1加载
newvalue[i]
并修改它。在线程1将其写入全局内存之前,线程2读取
newvalue[i]
也可以修改它。当您使用外部for循环在一个线程中迭代七次时,您可以在内核末尾使用原子加法或一种形式的reduce,但通常使用CUDA的方式是,启动的线程数与迭代次数相同。因此每个线程只计算外部循环的一次迭代。前提是如果迭代次数超过了可以启动的线程数,那么您必须考虑内核中某种形式的循环。但是您的内部循环应该留在内核中。啊,好吧。我认为总循环次数最多只有10000次左右,所以我假设我可以轻松拥有那么多线程。也许我会这样做?
kernelcall>(…)
并删除外部for循环。另外,感谢atomicadd的建议。我尝试实现它,但似乎仍然没有从内核获得正确的结果,但您也知道示例代码也不正确,因为它覆盖了
newvalues[I]
太多了?只是想一想,我会像这样调用内核,其中x是
dim2(total,total)
或类似的东西?我怎么能考虑到外部循环仅为to(total-1)干杯谢谢。我可以问你为什么选择16吗?一个16x16块有256个线程。我选择这个作为一个安全措施,以便代码可以在所有支持cuda的卡上运行。人们应该知道他们使用的卡的瓶颈和限制。费米体系结构支持每个块1024个线程,而前几代只支持每个块512个线程k、 因此,对于计算能力为2.0(费米)或更高的卡,您可以制作一个大小为32x32的块。对于计算能力小于2.0的卡,您需要将块大小保持在22x22以下。请阅读以下内容:
dim3 block(16,16);
dim3 grid (  (total+15)/16,  (total+15)/16  );
calc<<<grid,block>>>(float *val, float *newval, int T);
if (n>=total || i>=total)
return;