首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用CUDA计算二维像素数组,声明适当的网格和块大小

使用CUDA计算二维像素数组,声明适当的网格和块大小
EN

Stack Overflow用户
提问于 2013-11-23 19:01:05
回答 1查看 741关注 0票数 0

我使用CUDA来计算64x64x4数组的值,该数组已经被平放。数组包含GLubytes,然后在z列中存储任意给定像素的RGBA值。我已经创建了一个与CUDA一起使用的内核,但是我想我的块和网格的尺寸是关闭的。最终的结果不是画圆圈,而是画四分之一的圆圈。调用的内核和函数如下:

澄清:直径= 64,半径= 32。

代码语言:javascript
复制
__global__ void drawKernel(GLubyte *ball)
{
    int x = (blockIdx.x * blockDim.x) + threadIdx.x;
    int y = (blockIdx.y * blockDim.y) + threadIdx.y;


    ball[4 * (x * DIAMETER + y)+3] = (GLubyte) 0x0;  
    if ((x * x) + (y * y) <= (RADIUS * RADIUS)){ 
        ball[4 * ((x+32) * DIAMETER + (y+32))+0] = (GLubyte) 0xffffff;  
        ball[4 * ((x+32) * DIAMETER + (y+32))+1] = (GLubyte) 0x0; 
        ball[4 * ((x+32) * DIAMETER + (y+32))+2] = (GLubyte) 0x0; 
        ball[4 * ((x+32) * DIAMETER + (y+32))+3] = (GLubyte) 0xaaaaaa;
    }
}

cudaError_t drawWithCuda()
{
    size_t memorySize = DIAMETER * DIAMETER * 4 *sizeof(GLubyte);
    GLubyte *dev_ball = 0; //device ball
    cudaError_t cudaStatus; //CUDA error status
    dim3 threadsPerBlock(8, 8);
    dim3 numBlocks(DIAMETER/threadsPerBlock.x, DIAMETER/threadsPerBlock.y);

    // Choose which GPU to run on, change this on a multi-GPU system.
    cudaStatus = cudaSetDevice(0);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaSetDevice(0) failed! CUDA-capable GPU not on board.");
        goto Error;
    }

    // Allocate GPU buffers for GLubyte array 
    cudaStatus = cudaMalloc((void**)&dev_ball, memorySize);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMalloc failed!");
        goto Error;
    }

    //Begin CUDA-kernal call

    drawKernel<<<numBlocks, threadsPerBlock>>>(dev_ball);

    cudaDeviceSynchronize();

    //Copy from Device
    cudaStatus = cudaMemcpy(ball, dev_ball, memorySize, cudaMemcpyDeviceToHost);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "Device to Host failed!");
        goto Error;
    }

    Error:
        cudaFree(dev_ball);

    return cudaStatus;
}

我的问题是:我的问题在区块和网格的维度中找到了吗?或者是别的什么东西?

输出(一旦我通过openGL运行arrray球)如下所示:

我应该补充一点,当我不使用cuda并且只计算带有正则for循环的数组值时,内核中使用的逻辑工作得非常好,并绘制圆圈。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-23 21:55:15

您将分配这么多内存(在ball中):

代码语言:javascript
复制
    size_t memorySize = DIAMETER * DIAMETER * 4 *sizeof(GLubyte);

即一个深为64x64x4字节的数组。

现在让我们看看内核中的数组索引计算:

代码语言:javascript
复制
    ball[4 * ((x+32) * DIAMETER + (y+32))+0] = (GLubyte) 0xffffff; 

您的xy计算如下:

代码语言:javascript
复制
int x = (blockIdx.x * blockDim.x) + threadIdx.x;
int y = (blockIdx.y * blockDim.y) + threadIdx.y;

给定内核启动维度,您将启动一个直径x直径的线程数组,即64x64。因此,每个x从0到63不等,每个y从0到63不等,这取决于线程。

当我们将其中一些xy值插入内核时,索引计算就会崩溃(超过分配的内存):

代码语言:javascript
复制
    ball[4 * ((63+32) * 64 + (63+32))+0] = (GLubyte) 0xffffff; 

这超过了ball中的64x64x4可用区域。如果您使用cuda-memcheck运行这段代码,我很肯定您会看到超出界限的索引错误。

似乎您的数组索引应该如下所示:

代码语言:javascript
复制
    ball[4 * ((x) * DIAMETER + (y))+0] = (GLubyte) 0xffffff; 
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20166520

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档