我使用以下命令编译axpy.cu。
nvcc --cuda axpy.cu -o axpy.cu.cpp.ii
在
axpy.cu.cpp.ii
中,我观察到嵌套在 cudaLaunchKernel
中的函数 __device_stub__Z4axpyfPfS_
接受指向 axpy
中定义的函数指针。所以我的困惑是,不应该将函数指针传递给内核函数 axpy.cu.cpp.ii
吗?为什么会有与核函数同名的函数定义?任何帮助将不胜感激!预先感谢这两个功能如下所示。cudaLaunchKernel
axpy
所以我困惑的[原文如此]是,不应该将函数指针传递给内核函数
不,因为这不是 NVIDIA 选择的设计,并且您对该功能如何工作的假设可能不正确。据我了解,void axpy( float __cuda_0,float *__cuda_1,float *__cuda_2) # 3 "axpy.cu" { __device_stub__Z4axpyfPfS_( __cuda_0,__cuda_1,__cuda_2); }
的第一个参数被视为key,而不是被调用的函数指针。在 nvcc 发出的代码的其他地方,您会发现类似以下样板的内容:
cudaLaunchKernel
axpy
调用同时采用指向 cudaLaunchKernel
的静态指针和已编译 GPU 内核的损坏符号的形式。
static void __nv_cudaEntityRegisterCallback( void **__T0)
{
__nv_dummy_param_ref(__T0);
__nv_save_fatbinhandle_for_managed_rt(__T0);
__cudaRegisterEntry(__T0, ((void ( *)(float, float *, float *))axpy), _Z4axpyfPfS_, (-1));
}
是来自 CUDA 运行时 API 的内部、完全未记录的 API。许多年前,我对 CUDA 运行时 API 的早期版本进行逆向工程感到满意,因为有一个内部查找机制,允许主机内核存根的正确实例在运行时与已编译的 GPU 代码的正确实例相匹配。编译器会发出大量样板文件和静态定义的对象,其中包含所有必要的定义,以使运行时 API 无缝工作,而无需在 CUDA 驱动程序 API 或 OpenCL 等类似计算 API 中使用所需的所有额外 API 开销。
为什么会有与核函数同名的函数定义?因为这就是 NVIDIA 决定实现运行时 API 的方式。您所询问的是运行时 API 的未记录的内部实现细节。作为程序员,您不应该看到或使用它们,并且不保证它们在不同版本中都是相同的。
如果如注释中所示,您想在 CUDA 编译过程中实现一些额外的编译器基础设施,请使用 CUDA 驱动程序 API,而不是运行时 API。