nvcc - 在编译时取决于arch的不同块大小

时间:2013-11-07 22:12:48

标签: cuda c-preprocessor nvcc

我有一个内核,它在Kepler和Fermi硬件上运行时显示不同块大小的最高性能。我想在编译时检查当前的体系结构目标并定义一个THREADS_PER_BLOCK宏来i)启动内核; ii)确定所需的块数; iii)静态设置内核中的共享内存大小。

以下说明了我正在尝试做的事情。假设我的目标是GK104硬件,因此使用nvcc -arch=sm_30。这仍将导致THREADS_PER_BLOCK = 256,因为未为主机代码编译定义__CUDA_ARCH__。 (我理解,从例如this answer,为什么它不能以这种方式工作。)

#if __CUDA_ARCH__ >= 300
#define THREADS_PER_BLOCK 512
#else
#define THREADS_PER_BLOCK 256
#endif

__global__ void some_kernel(int* a, int* b) {
    __shared__ sm_data[THREADS_PER_BLOCK];
    // Do something.
}

int main(void) {
    // Initialize data.
    // Calculate blocks based on THREADS_PER_BLOCK, problem size and some max.
    some_kernel<<blocks, THREADS_PER_BLOCK>>>(d_a, d_b)
    return 0;
}

我可以在运行时检查设备属性并使用动态共享内存,但是想知道这是否可以在编译时进行硬编码,而不需要例如必须手动添加-DFERMI或-DKEPLER并根据它设置THREADS_PER_BLOCK。注意:此代码的任何用户都将自己编译,几乎当然对于一个架构,所以这不是一个不合理的选择。鉴于传递-arch=旗帜,这似乎是多余的。

1 个答案:

答案 0 :(得分:2)

nvcc编译器未检测到本地可用的GPU,默认情况下始终以SM 1.0为目标。否则,在不同的系统上构建时可能会引入一些相当混乱的行为。

要编译可用设备,您需要要求用户指定SM版本或在构建期间运行一些检测代码。我确信将硬件检测代码放入运行时更容易,然后根据需要配置内核启动。