如何在GPU中更正每个块的线程数?

时间:2019-03-26 00:57:59

标签: cuda gpu

我是使用CUDA编码GPU的新手。我尝试了一个有关使用GPU的简单示例(作为附加代码)。当我提取具有相同值的6个变量时,它将显示其他结果(例如,0 64832 64832 64832 0 64832而不是0 0 0 0 0 0)。但是,当我将THREADS_PER_BLOCK的值从1024更改为2时,它可以工作。你能帮我解释一下这种现象吗?

非常感谢您!

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <time.h>
using namespace std;
#define THREADGPU (360*180) 
#define THREADS_PER_BLOCK 1024

__global__ void calculation(double *xStartDraw, double *yStartDraw, double 
*zStartDraw,
double *xEndDraw, double *yEndDraw, double *zEndDraw)
{
int index = blockIdx.x * blockDim.x + threadIdx.x;

//cout with same value
xStartDraw[index] = index;
yStartDraw[index] = index;
zStartDraw[index] = index;
xEndDraw[index] = index;
yEndDraw[index] = index;
zEndDraw[index] = index;
}

int main(int argc, char **argv)
{
double *xStartDraw, *yStartDraw, *zStartDraw;
double *xEndDraw, *yEndDraw, *zEndDraw;
int size = THREADGPU * sizeof(double);
xStartDraw = (double *)malloc(size);
yStartDraw = (double *)malloc(size);
zStartDraw = (double *)malloc(size);
xEndDraw = (double *)malloc(size);
yEndDraw = (double *)malloc(size);
zEndDraw = (double *)malloc(size);

double *d_xStartDraw, *d_yStartDraw, *d_zStartDraw;
double *d_xEndDraw, *d_yEndDraw, *d_zEndDraw;
cudaMalloc((void **)&d_xStartDraw, size);
cudaMalloc((void **)&d_yStartDraw, size);
cudaMalloc((void **)&d_zStartDraw, size);
cudaMalloc((void **)&d_xEndDraw, size);
cudaMalloc((void **)&d_yEndDraw, size);
cudaMalloc((void **)&d_zEndDraw, size);

calculation <<< (THREADGPU + (THREADS_PER_BLOCK - 1)) / THREADS_PER_BLOCK, THREADS_PER_BLOCK
    >>> (d_xStartDraw, d_yStartDraw, d_zStartDraw, d_xEndDraw, d_yEndDraw, d_zEndDraw);

cudaMemcpy(xStartDraw, d_xStartDraw, size, cudaMemcpyDeviceToHost);
cudaMemcpy(yStartDraw, d_yStartDraw, size, cudaMemcpyDeviceToHost);
cudaMemcpy(zStartDraw, d_zStartDraw, size, cudaMemcpyDeviceToHost);
cudaMemcpy(xEndDraw, d_xEndDraw, size, cudaMemcpyDeviceToHost);
cudaMemcpy(yEndDraw, d_yEndDraw, size, cudaMemcpyDeviceToHost);
cudaMemcpy(zEndDraw, d_zEndDraw, size, cudaMemcpyDeviceToHost);


    for (int iRun = 0; iRun < THREADGPU; iRun++) 
    {
    cout <<iRun<<" "<<xStartDraw[iRun] <<" "<< yStartDraw[iRun] 
<<" "<< zStartDraw[iRun] <<" "<< xEndDraw[iRun] <<" "<< yEndDraw[iRun] <<" "<< zEndDraw[iRun] << endl;
}
free(xStartDraw);
free(yStartDraw);
free(zStartDraw);
free(xEndDraw);
free(yEndDraw);
free(zEndDraw);
cudaFree(d_xStartDraw);
cudaFree(d_yStartDraw);
cudaFree(d_zStartDraw);
cudaFree(d_xEndDraw);
cudaFree(d_yEndDraw);
cudaFree(d_zEndDraw);

return 0;
}

1 个答案:

答案 0 :(得分:2)

360 * 180不能被1024整除。因此,并非最后一个块中的所有线程都将具有有效的元素来工作,从而导致这些线程无法访问内存。但是360 * 180可以被2整除,这就是为什么它可以正常工作的原因……

除此之外:不要在C ++中使用malloc()。考虑使用智能指针(例如std::unique_ptr)来管理内存分配。 CUDA API调用确实返回错误代码,您应该检查该错误代码……

相关问题