【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];
}
相关推荐
irislinAmelia1 小时前
缺陷检测AI关键点在哪
人工智能·嵌入式硬件·1024程序员节
Ai-_Man1 小时前
Meta Muse还是不可以导出左侧所有对话,只能点进去单条内容导出,方法不对吗?
开发语言·人工智能·ai·小程序·c#·1024程序员节
安托智造1 小时前
MBD:从二维图纸到三维模型的制造革命(下)
大数据·人工智能·制造·mbd
火山引擎开发者社区1 小时前
VeOps 深度调查:让 AI 排障从“能用”走向“可靠”
人工智能
梓豪csd1 小时前
消息订阅中心:谁该收到哪条通知
java·开发语言·人工智能·低代码·自动化·1024程序员节
王中阳Go1 小时前
两个入口答案不一致先别调模型:6 行入口口径对账表(附脚本)
人工智能·后端·python·大语言模型·1024程序员节
武天旭1 小时前
AI安全--AI大模型的隐私保护与法律法规
人工智能·安全
Solange__1 小时前
影视预演怎么用AI生成3D场景?从分镜、Blockout到镜头交付的完整流程
人工智能·游戏·3d·ai·自然语言处理·aigc·游戏策划
冬奇Lab2 小时前
一次 Skill 评测的复盘:我推翻了一份现成的模型选型结论,然后自己造了个评测平台
人工智能·llm·agent
不脱发的程序猿3 小时前
纳指ETF量化策略
数据库·人工智能·1024程序员节