【问题标题】:CUDA: large kernel gives strange behaviorCUDA:大内核给出了奇怪的行为
【发布时间】:2013-08-17 05:48:59
【问题描述】:

我最近买了一张 gtx550ti 加速卡。以前在我的旧 gf440 卡上运行的程序失败了。这是一个例子。以下程序适用于较小的内核,但适用于较大的内核。

#include "stdio.h"

__global__ void kernel(float * d_in, float * d_out){
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
int idx = x + y * blockDim.x * gridDim.x;
d_out[idx] = d_in[idx];
}


int main(){
    const dim3 gridSize(10,10);
    const dim3 blockSize(80,80);
    const int size = 800*800;
    float * h_in  = new float[size];
    float * h_out = new float[size];
    float * d_in;
    float * d_out;
    cudaMalloc((void**)&d_in, sizeof(float)*size);
    cudaMalloc((void**)&d_out, sizeof(float)*size);
    for(int i = 0; i < size; i++)
        h_in[i] = (float)i;

    cudaMemcpy(d_in, h_in, sizeof(float)*size, cudaMemcpyHostToDevice);
    kernel<<<gridSize,blockSize>>>(d_in, d_out);
    cudaMemcpy(h_out, d_out, sizeof(float)*size, cudaMemcpyDeviceToHost);

    for(int i = 0; i < size; i++)
        printf("%f\n",h_out[i]);

    cudaFree(d_in);
    cudaFree(d_out);
    return 0;
}

我希望它以浮点数输出索引。但它会输出一些随机浮点数:

0.131061
2.520029
9.304665
0.000189
0.242134
0.525557
0.560013

尺寸 100*100

相反,当我切换到 100*100 尺寸时:

const dim3 gridSize(10,10);
const dim3 blockSize(10,10);
const int size = 100*100;

而且效果很好(最后 5 个输出):

9995.000000
9996.000000
9997.000000
9998.000000
9999.000000

尺寸 500*500

但对于更大的尺寸 500*500:

const dim3 gridSize(10,10);
const dim3 blockSize(50,50);
const int size = 500*500;

它输出错误的索引(最后5个输出):

512139.000000
512140.000000
512141.000000
512142.000000
512143.000000

我安装了 CUDA 5.5。谢谢!

【问题讨论】:

    标签: cuda


    【解决方案1】:

    每当您遇到 cuda 代码问题时,您都应该使用 proper cuda error checking

    这是无效的:

        const dim3 blockSize(80,80);
    

    这是要求 80*80 = 6400 个线程的线程块。没有任何 GPU 支持每个线程块 6400 个线程。

    这也是无效的:

    const dim3 blockSize(50,50);
    

    2500 个线程也太多了。这些配置不适用于您的任何一张卡。

    这是可以接受的:

    const dim3 blockSize(10,10);
    

    在“无效”的情况下,您的内核没有运行。如果您进行了适当的 cuda 错误检查,您就会发现这一点,甚至可以知道可能出现的问题(无效的启动配置)。

    您可能还想熟悉 deviceQuery cuda 示例,并研究 GPU 的输出。

    【讨论】:

    • 谢谢,1024 是块大小限制,也是每个维度的限制!那么每个网格的最大线程数是多少?
    • 据我所知没有指定。这是一个很大的数字,不管它是什么。
    • 每个多处理器的最大线程数:2048 网格大小的最大尺寸:(2147483647, 65535, 65535) 我有 4 个多处理器。我可以在内核中启动的最大线程数是多少?
    • 假设我想启动一个复制 2^30 个元素的内核。如何才能做到这一点?谢谢!
    • 请发布一个新问题。如果您愿意,您当然可以创建一个具有那么多线程的内核,每个线程复制一个元素。网格尺寸以 blocks 为单位,每个 block 最多可以有 1024 个线程。如果你算一算,你会发现我所说的大数是什么意思。它肯定不是“最大”的可能网格,但 1024*2147483647 是多少?这将是 cc3.x 设备的一维线程块/网格结构中的最大线程数。我不会再回答这些 cmets 中的任何新问题。
    猜你喜欢
    • 2021-12-10
    • 2014-01-24
    • 1970-01-01
    • 2020-12-15
    • 2019-04-01
    • 2011-06-28
    • 2014-08-08
    • 1970-01-01
    相关资源
    最近更新 更多