将 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);
。
这是我尝试对整数求和 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);
。