两个事实:CUDA 5.0允许您在不同的对象文件中编译CUDA代码以供稍后链接。CUDA架构2.x不再自动内联函数。
像往常一样,在C/C++中,我在functions.cu中实现了一个__device__ int foo()函数,并将其头文件放置在functions.hu中。其他CUDA源文件中调用函数foo。
当我检查functions.ptx时,我发现foo()会溢出到本地存储器。为了测试目的,我注释掉了foo()的所有内容,只是让它返回1; 根据.ptx仍然有东西溢出到本地存储器。(我无法想象它是什么,因为该函数什么也没做!)
但是,当我将foo()的实现移动到头文件functions.hu中并添加__forceinline__限定符时,就不会写入任何内容到本地存储器!
这里到底发生了什么?为什么CUDA不会自动内联这样一个简单的函数?
分离头文件和实现文件的整个重点是使我的生活更轻松地维护代码。但是,如果我必须将一堆函数(或所有函数)粘贴到头文件中并强制进行内联,那么这有点违背了CUDA 5.0不同编译单元的目的...
有没有什么方法可以解决这个问题?
简单的实际例子:
functions.cu:
像往常一样,在C/C++中,我在functions.cu中实现了一个__device__ int foo()函数,并将其头文件放置在functions.hu中。其他CUDA源文件中调用函数foo。
当我检查functions.ptx时,我发现foo()会溢出到本地存储器。为了测试目的,我注释掉了foo()的所有内容,只是让它返回1; 根据.ptx仍然有东西溢出到本地存储器。(我无法想象它是什么,因为该函数什么也没做!)
但是,当我将foo()的实现移动到头文件functions.hu中并添加__forceinline__限定符时,就不会写入任何内容到本地存储器!
这里到底发生了什么?为什么CUDA不会自动内联这样一个简单的函数?
分离头文件和实现文件的整个重点是使我的生活更轻松地维护代码。但是,如果我必须将一堆函数(或所有函数)粘贴到头文件中并强制进行内联,那么这有点违背了CUDA 5.0不同编译单元的目的...
有没有什么方法可以解决这个问题?
简单的实际例子:
functions.cu:
__device__ int foo
(const uchar param0,
const uchar *const param1,
const unsigned short int param2,
const unsigned short int param3,
const uchar param4)
{
return 1; //real code commented out.
}
上述函数会溢出到本地内存。
functions.ptx:
.visible .func (.param .b32 func_retval0) _Z45fooPKhth(
.param .b32 _Z45foohPKhth_param_0,
.param .b64 _Z45foohPKhth_param_1,
.param .b32 _Z45foohPKhth_param_2,
.param .b32 _Z45foohPKhth_param_3
)
{
.local .align 8 .b8 __local_depot72[24];
.reg .b64 %SP;
.reg .b64 %SPL;
.reg .s16 %rc<3>;
.reg .s16 %rs<4>;
.reg .s32 %r<2>;
.reg .s64 %rd<2>;
__forceinline__
所有函数)以保证内联是最佳实践吗? - cmo__forceinline__
和__noinline__
属性覆盖启发式算法。 - njuffa