GPU学习笔记

1. GPU 内存访问机制

GPU 的特点:

  • 每个 GPU 核心(线程)会处理一个小任务(比如一个粒子或一个像素)

  • 这些线程通常是 成组执行 的(称为 warpwavefront,NVIDIA 上是 32 个线程一组)

  • 这些线程会同时请求内存,如果它们访问的是连续的内存地址,GPU 会把这些请求合并(coalesced),一次性读入一块连续内存

  • 如果访问不连续,GPU 需要多次访问,效率大幅下降


1. GPU 并行执行的特点

GPU 的线程是 成组执行 (NVIDIA 叫 warp,AMD 叫 wavefront),比如 NVIDIA 是 32 个线程一组

  • 这一组线程同时执行同一条指令(SIMD/Single Instruction Multiple Data)

  • 如果所有线程都做同样的操作,执行非常快

  • 如果有条件分支 (if),情况就复杂了

2. 为什么 if 会慢

假设你有这样一个代码片段:

if (condition)

doA();

else

doB();

  • 如果条件在 warp 内所有线程一致 → GPU 一次执行 doAdoB,效率正常

  • 如果条件不同(warp divergence) → GPU 需要:

    1. 先执行满足条件的线程

    2. 再执行不满足条件的线程

    3. 最后合并结果

这个过程叫 warp divergence ,会导致部分线程闲置,吞吐量下降。

2. 分支情况下(warp divergence)

假设 warp 内线程条件不一致:

复制代码

if (condition)

doA();

else

doB();

  • GPU 内部处理方式:

    1. 执行满足条件的线程 doA() → 其他线程被掩盖(idle)

    2. 执行不满足条件的线程 doB() → 前面 idle 的线程现在执行,原来的 doA 线程 idle

    3. 恢复线程状态,合并结果

结果:每条指令可能要执行两次(甚至更多,如果条件更多),导致部分线程在每次执行时闲置 → 实际吞吐量下降。


3. 性能消耗量化

假设:

  • 没有分支:warp 执行一次操作,32 个线程都忙 → 100% 利用率

  • 有分支:16 个线程做 doA,16 个做 doB

那么:

  • 执行 doA:16 个线程有效,16 个线程 idle → 利用率 50%

  • 执行 doB:16 个线程有效,16 个线程 idle → 利用率 50%

  • 平均下来,这条指令的 warp 利用率 = 50%

可以看出,理论上 warp divergence 会直接降低吞吐率,性能消耗很明显,尤其在大量分支和大 warp 的情况下。


为什么很多代码只用 dot(a,a)

在很多图形学 / 游戏 / shader 里,经常直接用 dot(a,a),原因是:

  • 不用 sqrt,计算更快

  • 如果只是比较距离大小,用平方就够了

平方非常便宜,sqrt 相对贵很多,但"贵多少"取决于硬件和编译器。总体规律在 CPU / GPU 上都差不多。

1️⃣ 运算成本对比(大致级别)

运算 大致成本
加 / 减 非常便宜(1 cycle 左右)
乘法(平方就是乘法) 很便宜(1--3 cycles)
除法 比乘法贵很多
sqrt 明显更贵

在计算机图形学和 GPU 编程中,Warp(线程束)是 GPU 执行线程的一种调度单位。简单来说:

Warp = 一组同时执行同一条指令的线程集合。

最常见的情况是在 NVIDIA GPU 架构中:

  • 1 个 Warp = 32 个线程

  • 这 32 个线程会 锁步(lockstep)执行同一条指令

  • Warp 是 GPU 调度器分配执行的最小单位

每个线程的数据不同 指令相同?

1 什么叫 指令相同

假设有一段 Shader / GPU 代码:

color = textureColor * light;

GPU 在某一时刻执行的 指令 其实是类似:

MUL r0, r1, r2

意思是:

r0 = r1 * r2

在一个 Warp(32个线程) 中:

所有线程此刻都在执行这一条 MUL 指令。

所以叫:

Single Instruction(单条指令)


2 什么叫 数据不同

虽然执行的指令一样,但每个线程操作的数据不同

例如在 Pixel Shader 里:

屏幕有很多像素:

pixel0

pixel1

pixel2

pixel3

...

Warp 中:

thread0 → pixel0

thread1 → pixel1

thread2 → pixel2

thread3 → pixel3

...

当执行:

color = textureColor * light

实际上发生的是:

thread0: color0 = texture0 * light0

thread1: color1 = texture1 * light1

thread2: color2 = texture2 * light2

thread3: color3 = texture3 * light3

相关推荐
csdn小瓯12 小时前
LangGraph自适应工作流路由机制:从关键词匹配到智能决策的完整实现
人工智能·fastapi·langgraph
QYR-分析12 小时前
高功率飞秒激光器行业发展现状、市场机遇及未来趋势分析
大数据·人工智能
AI医影跨模态组学13 小时前
J Clin Oncol(IF=43.4)美国Cedars-Sinai医学中心等团队:基于计算组织学人工智能的晚期胰腺癌化疗选择预测性生物标志物的开发与验证
人工智能·机器学习·论文·医学·医学影像·影像组学
冬奇Lab13 小时前
RAG 系列(十六):Graph RAG——用知识图谱解决多跳关系问题
人工智能·llm
冬奇Lab13 小时前
一天一个开源项目(第101篇):OpenHuman - 真正懂你的本地优先个人 AI 超级助手
人工智能·开源·资讯
云上码厂13 小时前
专业的学术会议 / 讲座视频与幻灯片托管、回放平台(可以使用SlidesLive 学英语入门清单)
人工智能
无心水13 小时前
【Hermes:安全、权限与生产环境】40、运行 Hermes 前的生命线:安全审计清单与 11 个必须检查的配置项
人工智能·安全·mcp协议·openclaw·养龙虾·hermes·honcho
温九味闻醉14 小时前
关于腾讯广告算法大赛2025项目分析3-重读
人工智能·机器学习
十铭忘14 小时前
AI画架构图的方法
人工智能
chatexcel14 小时前
AI知识库教程:基于ChatExcel实现规则文档、Excel数据与业务分析联动
人工智能·excel