调用__device__函数会影响CUDA中使用的寄存器数量吗?

时间:2015-12-02 15:14:34

标签: performance cuda inline

我已经在各个地方读过,__device__函数几乎总是由CUDA编译器内联。那么说,当我将代码从内核移动到内核调用的__device__函数时,通常没有增加寄存器的数量吗?

例如,以下代码段使用相同数量的寄存器吗?它们同样有效吗?

SNIPPET 1

__global__ void manuallyInlined(float *A,float *B,float *C,float *D,float *E) {
    // code that manipulates A,B,C,D and E 
}

SNIPPET 2

__device__ void fn(float *A,float *B,float *C,float *D,float *E) {
    // code that manipulates A,B,C,D and E 
}


__global__ void manuallyInlined(float *A,float *B,float *C,float *D,float *E) {
    fn(A,B,C,D,E);
}

1 个答案:

答案 0 :(得分:3)

最终答案只能通过使用工具(使用-Xptxas -v编译,或使用其中一个分析器)来确定,但一般的答案是调用__device__函数可以< / em>影响使用的寄存器数量(以及性能和效率)。

根据您的文件组织以及编译代码的方式,__device__功能可能为inlined。如果它是内联的,这通常会给优化编译器(主要是ptxas)提供最适合调整寄存器使用的机会。 (注意,至少在理论上,这个&#34;适应&#34;可能会导致 或多或少使用。但是,内联案例通常会导致编译器使用较少的寄存器和可能性能更高。但编译器主要优化以获得更高的性能,而不是更少的寄存器使用。)

另一方面,如果它没有内联,则必须将其作为普通函数调用处理。与许多其他计算机体系结构一样,函数调用涉及设置堆栈帧以传递变量,然后将控制转移到函数。在这种情况下,编译器受到更多限制,因为:

  1. 必须将函数使用的变量移入/移出堆栈框架
  2. 它不能执行基于&#34;周围&#34;的其他优化。代码,因为它不知道周围的代码是什么。 __device__函数必须由编译器以独立方式处理。
  3. 因此,如果函数可以内联,那么两种方法之间应该没有太大区别。如果无法内联函数,那么上述两种方法中的寄存器使用通常会有明显的差异。

    可能影响编译器是否会尝试内联__device__函数的一些明显因素是:

    1. 如果__device__函数与调用它的__global__或其他__device__函数位于单独的编译单元中。在这种情况下,唯一可行的方法是通过CUDA separate compilation and linking,也称为设备链接。在这种情况下,编译器不会(不能)内联函数。

    2. 如果指定了__noinline__ compiler directive。请注意,这只是编译器的一个提示;它可能会被忽略。