为什么 CUDA 函数 cudaLaunchKernel 将函数指针传递给主机代码函数?

问题描述 投票:0回答:1

我使用以下命令编译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

	
所以我困惑的[原文如此]是,不应该将函数指针传递给内核函数
cuda function-pointers
1个回答
4
投票

不,因为这不是 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。

© www.soinside.com 2019 - 2024. All rights reserved.