工作原因,需要了解一下 GPU 的硬件和 CUDA 的对应关系和调度方法。由于不是专职优化 GPU 代码,所以就是个大概了解。
TL;DR
- Perfect solution for {数据并行}
- 硬件设计思路:
1. 高吞吐,低响应
2. 无需 cache (目前实际硬件有),无需复杂的指令调度(多个线程走的都是一样的指令)
3. 节约硬件空间(一次 fetch/decode/dispatch 就可以支持很多个线程,也没有 branch prediction/乱序等等优化需求,硬件空间全省)
4. 可以塞更多的 ALU,增加算力。
- 上下文切换可以认为是 0(每个 cycle 都可以切换,寄存器、指令都是同时分配很多个线程的,也就是说线程上下文都准备好了,没有切换开销)。
- 调度基本单位是 warp (目前是一个 warp 是 32 threads),基本硬件调度是 SM。
- 每个 SM 会跑一个 warp,同时等待 N 个 warp 随时可以切换(就看寄存器 shared mem 大小),这 N + 1 个 warp 都是 active 的。
- 如果程序设计良好,active warp 达到了硬件最大支持就可以认为程序的 occupancy 比较高(如果程序已经可以撑满内存的带宽,此时的 occupancy 也就足够了)。
- 多用 shared mem 作为缓存管理可以提升速度,不过会有 bank conflict。
- Thread Divergence 如果 if else 逻辑复杂需要考虑下。
A. 内存模型
![806c45e26eab7396ca6eaf6925debe64.png](https://i-blog.csdnimg.cn/blog_migrate/cdf8785e112ab1ed860f32f09064d8b2.png)
内存特性
![c73decf13c947b5c33e93b0cf10b89ac.png](https://i-blog.csdnimg.cn/blog_migrate/3c257a3e190cbfd90b37848b5b9c890b.jpeg)
- 由于 shared mem 的性能良好,所以可以考虑将 global mem 的数据先载入到 shared mem 来提升性能。
- 在 CUDA 11 里面提供了一个新的方法:async-copy,可以