0

我制作了一个 CUDA 程序,但遇到了一个问题。我有两个功能:

  1. __global__ void cal_freq_pl(float *, char *, char *, int *, int *)
  2. __global__ void cal_sum_vfreq_pl(float *, float *, char *, char *, int *)

我这样调用第一个函数: cal_freq_pl<<<M,512>>>( ... ); M 是一个大约 15 的数字,所以我并不担心。512 是我的 GPU 上每个块的最大线程数。这工作正常,并为所有 M*512 值提供了预期的输出。

但是当我以类似的方式调用第二个函数时: cal_sum_vfreq_pl<<<M,512>>>( ... ); 它不起作用。在调试了那个函数的废话之后,我终于发现它以这些尺寸运行:cal_sum_vfreq_pl<<<M,384>>>( ... );,比 512 少 128。它显示 512 没有错误,但结果不正确。

我目前只能访问 Compute1.0 arch 并且在 Windows 64 位机器上拥有 Nvidia Quadro FX4600 显卡。

我不知道为什么会发生这种行为,我确信第一个函数正在运行 512 个线程,而第二个函数只运行 384 个(或更少)。

有人可以建议一些可能的解决方案吗?

提前致谢...

编辑:这是内核代码:

__global__ void cal_sum_vfreq_pl(float *freq, float *v_freq_vectors, char *wstrings, char *vstrings, int *k){
    int index = threadIdx.x;
    int m = blockIdx.x;
    int block_dim = blockDim.x;
    int kv = *k; int vv = kv-1; int wv = kv-2;
    int woffset = index*wv;
    int no_vstrings = pow_pl(4, vv);
    float temppp=0;
    char wI[20], Iw[20]; int Iwi, wIi;
    for(int i=0;i<wv;i++) Iw[i+1] = wI[i] = wstrings[woffset + i];
    for(int l=0;l<4;l++){
            Iw[0] = get_nucleotide_pl(l);
            wI[vv-1] = get_nucleotide_pl(l);
            Iwi = binary_search_pl(vstrings, Iw, vv);
            wIi = binary_search_pl(vstrings, wI, vv);
            temppp = temppp + v_freq_vectors[m*no_vstrings + Iwi] + v_freq_vectors[m*no_vstrings + wIi];
    }
    freq[index + m*block_dim] = 0.5*temppp;
}
4

1 回答 1

1

看来您在第二个内核中分配了很多寄存器。由于硬件资源限制(例如每个块的寄存器数量),您不能总是达到每个块的最大线程数。

CUDA 提供了一个工具来帮助计算每个块的正确线程数。

http://developer.download.nvidia.com/compute/cuda/CUDA_Occupancy_calculator.xls

您还可以在 CUDA 安装目录中找到此 .xls 文件。

于 2013-02-05T11:22:35.580 回答