☰
CUDA C:核函数、主机函数、设备函数
2026/10/27 9:24:54 网站建设 项目流程

相关阅读

CUDA Chttps://blog.csdn.net/weixin_45791458/category_12530616.html?spm=1001.2014.3001.5482


在CUDA编程模型中,函数按照调用位置和执行位置的不同,可以分为核函数(Kernel Function)、主机函数(Host Function)和设备函数(Device Function)。CUDA通过不同的函数限定符来描述这些函数的属性,这也是理解CUDA程序执行机制的基础。

核函数是指由主机(CPU)发起调用,并在设备(GPU)上执行的函数。在某些情况下,支持动态并行的设备也可以从设备端调用核函数。核函数使用__global__限定符进行修饰。核函数通常是CUDA并行计算的入口,线程块(block)和线程(thread)会围绕核函数展开执行,因此它是CPU计算任务的核心组成部分。

主机函数是指在主机(CPU)上调用,并且也在主机(CPU)上执行的函数。它可以显式使用__host__限定符修饰,不过在实际编程中这一限定符通常可以省略,因为普通的C/C++函数默认就是主机函数。也就是说,如果一个函数没有使用CUDA特殊限定符,那么通常就可以把它看作主机函数。

设备函数是指只能在设备(GPU)端被调用,并且在设备(GPU)上执行的函数,使用__device__限定符修饰。这类函数通常不能直接由CPU调用,而是作为GPU上其他函数(如核函数或设备函数)的辅助函数使用,用于实现更清晰的模块化设计。

其中__host__和__device__还可以同时修饰同一个函数,表示该函数既可以在主机端调用并执行,也可以在设备端调用并执行。这种写法常用于一些逻辑较简单、希望同时适配CPU和GPU的函数,有助于提高代码复用率,减少重复实现。

上面的函数修饰符信息总结于表1。

表1 函数类型限定符

限定符调用位置执行位置备注
__global__可由主机调用,也可由计算能力 3.0 及以上的设备调用设备核函数
__host__主机主机可省略
__device__设备设备设备函数

CUDA提供了一系列运行时(Runtime)API供开发者使用。这些API大多数属于主机函数,也就是说它们通常由CPU端代码调用;当然,也有少量API同时具备主机函数和设备函数的属性。

例如,下面这个内存拷贝API就是一个典型的主机函数:

__host__ ​cudaError_t cudaMemcpy ( void* dst, const void* src, size_t count, cudaMemcpyKind kind )

这个函数中的返回值​是一个cudaError_t枚举类型,参数dst是目标内存指针,参数src是源内存指针,参数count是需要拷贝的字节数,参数kind是一个cudaMemcpyKind枚举类型。

· 其中,枚举类型cudaMemcpyKind用于指定数据传输的方向,其定义如下:

cudaMemcpyHostToHost = 0 //Host -> Host cudaMemcpyHostToDevice = 1 //Host -> Device cudaMemcpyDeviceToHost = 2 //Device -> Host cudaMemcpyDeviceToDevice = 3 //Device -> Device //Direction of the transfer is inferred from the pointer values. Requires unified virtual addressing cudaMemcpyDefault = 4

从这些枚举值可以看出,cudaMemcpy能够支持主机与设备之间、设备与设备之间以及主机与主机之间的数据传输。其中,cudaMemcpyDefault会根据指针类型自动推断传输方向,但它依赖统一虚拟寻址(Unified Virtual Addressing, UVA)机制。

再看另一个常用的同步 API:

__host__​__device__​cudaError_t cudaDeviceSynchronize ( void )

这个函数既是主机函数,也是设备函数。它的作用是进行设备同步,即等待当前设备上的任务执行完成后再继续后续操作。

在CUDA编程中,由于很多操作是异步执行的,因此同步函数十分重要。合理使用同步函数有助于程序调试、结果验证以及执行流程控制。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询