当块数较大时,CUDA GPU可获得惊人的效果
最近我与CUDA编程一起工作,当blockNum超过500时,我遇到了一个令人难以置信的问题。为了简化模式,我编写了以下测试代码:当块数较大时,CUDA GPU可获得惊人的效果,cuda,gpu,block,Cuda,Gpu,Block,最近我与CUDA编程一起工作,当blockNum超过500时,我遇到了一个令人难以置信的问题。为了简化模式,我编写了以下测试代码: #include <assert.h> #include <cuda.h> #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <cuda_runtime.h> #include <device_lau
#include <assert.h>
#include <cuda.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
/* Example from "Introduction to CUDA C" from NVIDIA website:
https://developer.nvidia.com/cuda-education
Compile with:
$ nvcc example_intro.cu */
#define num 1000
const int N = num*32*12;
__global__ void add_blocks (int *a, int *c) {
int threadId = blockIdx.x * blockDim.x * blockDim.y
+ threadIdx.y * blockDim.x + threadIdx.x;
int block_id = threadIdx.y;
if(threadId % 2 == 0){
c[threadId] = 1;
}
}
int main(void) {
int *a, *c;
int *d_a, *d_c; /* Device (GPU) copies of a, b, c */
size_t size = N * sizeof(int);
/* Allocate memory in device */
cudaMalloc((void **) &d_a, size);
cudaMalloc((void **) &d_c, size);
/* Allocate memory in host */
a = (int *) malloc(size);
c = (int *) malloc(size);
/* Allocate random data in vectors a and b (inside host) */
for (int i = 0; i < N; ++i) {
a[i] = 0;
c[i] = 0;
}
/* Copy data to device */
cudaMemcpy(d_a, a, size, cudaMemcpyHostToDevice);
dim3 threads_per_block(32, 12);
add_blocks<<<num, threads_per_block>>>(d_a,d_c);
cudaMemcpy(c, d_c, size, cudaMemcpyDeviceToHost);
cudaError_t errSync = cudaGetLastError();
if (errSync != cudaSuccess)
printf("Sync kernel error: %s\n", cudaGetErrorString(errSync));
int counter = 0;
for (int i = 0; i < N; ++i) {
if(c[i] == 1){
counter ++;
}
}
printf("%d\n",counter);
/* Clean-up */
free(a);
free(c);
cudaFree(d_a);
cudaFree(d_c);
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
/*NVIDIA网站“CUDA C简介”示例:
https://developer.nvidia.com/cuda-education
编译时使用:
$nvcc示例_intro.cu*/
#定义num 1000
常数int N=num*32*12;
__全局无效添加块(int*a,int*c){
int threadId=blockIdx.x*blockDim.x*blockDim.y
+threadIdx.y*blockDim.x+threadIdx.x;
int block_id=threadIdx.y;
如果(线程ID%2==0){
c[threadId]=1;
}
}
内部主(空){
int*a,*c;
int*d_a、*d_c;/*设备(GPU)a、b、c的副本*/
大小=N*sizeof(int);
/*在设备中分配内存*/
Cudamaloc((空隙**)和d_a,尺寸);
Cudamaloc((空隙**)和d_c,尺寸);
/*在主机中分配内存*/
a=(int*)malloc(大小);
c=(int*)malloc(大小);
/*在向量a和b中分配随机数据(主机内部)*/
对于(int i=0;i
当threadnum是2的倍数时,我将c数组设置为1,最后我计算num为1,我认为是N/2。当block num小于500时,它工作得很好,例如num*32*12/2=500*32*12/2=96 000。但是当num为1000时,结果是312846,应该是192000。有人能帮我吗?谢谢大家。问题出在以下代码中:
int counter = 0;
for (int i = 0; i < N; ++i) {
if(c[i] == 1){
counter ++;
}
}
printf("%d\n",counter);
int计数器=0;
对于(int i=0;i
您隐式地假设
c
中的每个值1都必须由先前的GPU内核设置。但是,您根本没有在d_c
中设置一半元素的值(因此在程序的这一点上,c
),因此无法保证其中一些元素的值也不会为1。读取和使用单元化内存的值并不令人惊讶,这只是一种糟糕的编程实践。我确信有时它“在block num低于500时无法正常工作”。这个问题与你运行的块数无关谢谢你的回答,我昨天意识到了这个错误,但是现在测试它已经太晚了,我只是去睡觉了。走开,谢谢你,我会注意这种虫子的。