将 1 到 100 int 值相加,然后在 CUDA 中对 float 值求和

Sum 1 to 100 int value and then float values in CUDA

这是我尝试对整数求和 1 到 100 的方法,结果输出为 0。

#include <stdio.h>
#include <cuda.h>

__device__ int sum;

__global__ void kernel(){
    sum =0;
    atomicAdd(&sum, threadIdx.x);
    printf("%d",sum);
}

int main(){
    kernel<<<1,100 >>>();
    printf("%d",sum);
    return 0;
}

此外,由于浮点数不支持原子操作,因此我没有得到任何线索来计算浮点数 1 到 100 的总和。

排名不分先后:

  • 您不应该像现在这样在内核代码中初始化 sum。所有线程都会这样做,并且 CUDA 没有强加特定的线程执行顺序。不要假设所有线程都会在任何线程继续执行下一个之前执行 sum = 0; 语句。
  • 您不能在主机代码中直接打印 __device__ 变量。 nvcc 应该警告你
  • 您应该小心使用正确的 printf 格式说明符
  • 在打印结果之前,您必须等待内核完成,或强制内核完成。
  • 您可以对 float 个变量执行 atomicAdd。参见 here
  • 我建议进行适当的 CUDA 错误检查。

这是解决了这些问题的代码。如果您想查看浮动行为,请将 typedef 从 int 更改为 float

$ cat t1895.cu
#include<stdio.h>

typedef int mt;
__device__  mt sum = 0;

__global__ void kernel(){


  atomicAdd(&sum, threadIdx.x);
  //printf("%f",(float)sum);

}

int main(){

  kernel<<<1,100 >>>();
  mt my_result;
  cudaMemcpyFromSymbol(&my_result, sum, sizeof(mt));
  printf("%s\n", cudaGetErrorString(cudaGetLastError()));
  printf("%f\n",(float)my_result);
  return 0;
}
$ nvcc -o t1895 t1895.cu
$ cuda-memcheck ./t1895
========= CUDA-MEMCHECK
no error
4950.000000
========= ERROR SUMMARY: 0 errors
$

请注意,实际上这段代码是对 0-99 而非 1-100 的值求和。如果您想查看 1-100 的总和,请将您的线程块大小从 100 增加到 101(即求和 0-100),或者在您的内核代码中执行 atomicAdd(&sum, threadIdx.x+1);