CUDA与AscendC对比(三)

举报
黄生 发表于 2026/06/07 20:48:15 2026/06/07
【摘要】 __global__ 是一个函数类型限定符,它告诉编译器这个函数是一个核函数(Kernel) 既然如此,叫kernel不是更直观?厂商关键字平台NVIDIA (CUDA)__global__GPUAMD (ROCm/HIP)__kernel__GPUOpenCL (跨平台)__kernel各种加速器Ascend C (华为)__global__ __aicore__NPU __kernel_...

__global__ 是一个函数类型限定符,它告诉编译器这个函数是一个核函数(Kernel) 既然如此,叫kernel不是更直观?


厂商 关键字 平台
NVIDIA (CUDA) __global__ GPU
AMD (ROCm/HIP) __kernel__ GPU
OpenCL (跨平台) __kernel 各种加速器
Ascend C (华为) __global__ __aicore__ NPU

__kernel__ 被AMD和OpenCL用了,NVIDIA选择了不同的名字。

  1. 2006年CUDA刚出来时,"kernel"这个词在并行计算领域已经被OpenCL(2009年才发布)之前的Brook、Sh等研究项目广泛使用。

  2. 语义准确性:__global__ 强调的是函数的可见性和调用范围——它既可以被Host(CPU端)调用,又运行在Device(GPU端)上,是一种"全局"的函数。而"kernel"在操作系统里已经有含义(内核态),可能会引起混淆。

CUDA内部其实也有__device____host__

__global__ void kernel_1() {...}   // 被CPU调用,在GPU上执行
__device__ void kernel_2() {...}   // 被GPU调用,在GPU上执行
__host__ void kernel_3() {...}     // 被CPU调用,在CPU上执行(普通函数)
__host__ __device__ void kernel_4() {...} // 既可在CPU也可在GPU

这里__global__的特殊性就体现出来了:它是唯一一个被Host启动的关键字。

最后说一句:__global__函数是唯一一个可以被CPU代码调用、但实际在GPU上执行的函数。应该没错吧。


核函数(Kernel)只是在设备上运行的函数,为什么叫核函数呢?这个核很容易让人联想到Linux的内核态,但与之又毫不相干


CUDA 的“核”指的是计算核心 (Core),而不是操作系统内核 (Kernel)。这个命名源于 GPU 硬件本身的结构。在 GPU 架构中,执行计算任务的基本单元叫做“核心”(Core)。英伟达 GPU 里有成百上千个 CUDA 核心,AMD GPU 里有流处理器,华为昇腾 NPU 里有 AI Core。因此,一个在“核心”上执行的函数,就被自然地称为“核函数”(Kernel Function)。这个叫法更精准地区分了普通 CPU 函数和并行设备函数,并且在学术界和工业界都作为标准术语被广泛使用。它虽然借用了英文词 Kernel,但指向的是硬件核心 (Core),而不是操作系统内核。


英伟达 GPU 里有成百上千个 CUDA 核心。这个核心是前面说到的warp吗?还是thread?


  • CUDA 核心 (Core): 这是一个物理硬件。你可以把它理解为GPU里的一个计算器或算术逻辑单元。它在一个时钟周期内只能做一个简单的运算(比如一次浮点数加法)。

  • Thread (线程): 这是一个逻辑概念。它是你写代码时,一个任务的最小执行单元。

  • Warp (线程束): 这是一个调度单位,是一个逻辑概念。它是32个Threads的集合。你可以把它理解为一个小任务组。

概念 它是物理的吗? 它的作用 举个具体例子 (RTX 4090)
CUDA 核心 是 (物理的) 执行具体加减乘除的硬件单元 有 16384 个
SM 是 (物理的) 包含CUDA核心、调度器的核心模块 有 128 个 (每个SM内含128个CUDA核心)
Thread 否 (逻辑的) 一次计算的最小虚拟任务 你可以创建任意多个 (例如 100 万个)
Warp 否 (硬件的调度单位) 32个Threads 组成的调度小组 你代码里的线程,被GPU自动每32个分为一组

Warp (32个线程) 是 SM 接收和调度任务的基本单位,而 CUDA核心 只是 SM 内部用来实际做计算的工具。所以,当你听到“GPU有几千个核心”时,你应该理解为“GPU有几千个可以做简单计算的硬件单元”,而不是“同时独立运行几千个不同任务的处理器”。


__global__ __aicore__ 这里的 aicore 是否多余,是不是因为NPU上还有AI CPU单元,而GPU没有?


NVIDIA GPU的核心计算单元类型相对单一。虽然它内部有负责调度的SM(流多处理器)和负责计算的CUDA核心,但它们本质上是同一套逻辑单元。因此,当一个函数被标记为 __global__ 时,编译器和硬件非常清楚:这就是要在GPU的通用计算核心上跑,没有第二种可能。

昇腾AI处理器内部存在多种专门化的计算单元。

  • AI Core。它内部集成了强大的Vector(向量)单元和Cube(立方体)单元,专门用来加速深度学习中大量的矩阵、向量运算,是执行AI算子的主力。

  • AI CPU:昇腾NPU内部除了AI Core,还集成了AI CPU。它主要负责执行一些逻辑复杂的、不太适合AI Core处理的任务,比如数据预处理、后处理,或者作为某些特殊算子的备选执行单元。

正是因为存在这两种功能迥异的“核”,编译器就必须明确知道:“嘿,我这段代码到底要扔给AI Core算,还是扔给AI CPU算?”

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。