【CUDA1】GPUvsCPU,CUDA Kernel

这个系列我们来讲解CUDA,从入门到可以独立写自己的cuda代码,现在开启我们的cuda之旅吧。

CPU:少量非常强的核心,一个核心很强,擅长:

  • 复杂逻辑
  • 分支判断
  • 操作系统
  • Python 程序
  • 各种串行任务

GPU:大量相对简单的计算单元,同时执行大量相似任务。

CPU有内存,RAM,GPU有显存,VRAM。

复制代码
x = torch.randn(1000, 1000)//默认是CPU RAM
print(x.device)//CPU

x = torch.randn(1000, 1000, device="cuda")//GPU VRAM
print(x.device)//cuda:0 第 0 张 NVIDIA GPU

y = torch.randn(1000, 1000, device="cuda")

z = x @ y//矩阵乘法

第一个程序(建议手写)

python 复制代码
import torch  
  
print("CPU:")  
x = torch.randn(3,3)  
print(x)  
print("device:",x.device)  
  
  
print()  
  
print("GPU:")  
y = torch.randn(3,3,device="cuda")  
print(y)  
print("device:",y.device)

什么是CUDA kernel?

可以把它理解为让 GPU 执行的一段程序,比如我们需要Ci = Ai + Bi;有1亿个元素,GPU启动大量线程

复制代码
Thread 0 → C[0] = A[0] + B[0]

Thread 1 → C[1] = A[1] + B[1]

Thread 2 → C[2] = A[2] + B[2]

Thread 3 → C[3] = A[3] + B[3]

...

Thread 99999999 → C[99999999] = ...

当然GPU不是真的同时拥有这么多的物理计算核心,所以我们需要把thread分组,若干个thread合成一个block,我们再将所有的block集合为grid,于是形成了一个层级结构

复制代码
                 Grid
                  │
       ┌──────────┼──────────┐
       ↓          ↓          ↓
    Block 0    Block 1    Block 2
       │          │          │
    Threads    Threads    Threads

GPU内部存在一种叫SM的计算单位,暂时可以理解为GPU里面真正负责执行CUDA Thread的计算单元。我们现在不讨论这个,就直接进入threads步骤,每个thread都有自己的ID,CUDA给我们提供threadIdx来获取thread的编号

eg:int i = threadIdx.x;//c++

Ci = Ai + Bi;//thread就知道自己负责谁了

这个i其实不会太大,因为block的存在,如果大了的话,我们会换一个block,同样的,CUDA提供blockIdx表示我是第几个block,再加上threadIdx,表示我是这个block的第几个thread,于是全局的Thread ID可以计算

c++ 复制代码
int i = blockIdx.x*blockDim.x+threadIdx.x;

我们来算一下,block0 thread0是多少?

假设每个block有256个thread

int i = 0 * 256+0=0;这个就是CUDA把大数组分给GPU的核心方法。

CUDA程序实际上是在协调CPU和GPU。

复制代码
             CPU
              │
              │ 启动 Kernel
              ↓
             GPU
              │
              ↓
          CUDA Kernel
              │
       ┌──────┼──────┐
       ↓      ↓      ↓
     Thread Thread Thread

first CUDA

我们之前写的import torch,它使用torch库来直接调用CUDA Kernel,现在我们开始接触真正的CUDA C++。

复制代码
__global__ void add(float* A, float* B, float* C)
{
    int i = blockIdx.x * blockDim.x + threadIdx.x;

    C[i] = A[i] + B[i];
}
相关推荐
thesky1234561 小时前
用 ONNX Runtime 把 PyTorch 模型变成跨平台极速推理引擎:导出、优化、量化完整实
人工智能·深度学习·模型部署
米小虾1 小时前
把 KV Cache 从 3514 字节压到 890 字节:DeepSeek V4.1-Flash 动了什么,又没动什么
人工智能
锋行天下1 小时前
LangGraph 进阶:Command + Send 动态控制流、并行 Map-Reduce 实战与踩坑
人工智能
米小虾1 小时前
AI 观察:CEO 们集体喊"慢一点",钱却在加速进场
人工智能
微三云生态系统架构师-彭丹2 小时前
远方好物S2B2C系统架构:一级分销与保证金托管的合规技术实现
人工智能·算法
冬奇Lab2 小时前
DeepSeek Harness 系列(06):System Prompt 组装——动态提示词的工程实现
人工智能·deepseek
罗西的思考3 小时前
机器人模型(WM / WAM / VLA)综合分析与对比:从「看」到「想」再到「做」
人工智能·算法·机器学习
火山引擎开发者社区4 小时前
基于 AgentKit 的端到端需求交付平台:从个人提效到组织提效的 AI 落地实践
人工智能
三声三视4 小时前
75 条文章索引被一条 add 清成 1 条,退出码还是 0:tri-article 的 index.py 我读了 205 行
人工智能·ai·skill·tri-skills·tri-article