第 18 章 GPU 与异构计算
GPU 是异构计算最典型的形态:它有自己的内存、自己的执行模型与自己的命令队列,挂在主机一侧,经由一条 FFI 边界与 Go 程序相连。本章讨论的是这条边界本身,后面几章的图形、推理与 Agent 都建立在这里的结论之上。
18.1 讨论跨界的开销:一次 cgo 调用的固定成本、GPU 命令「入队即返回」的异步语义、kernel 的启动开销,以及通过异步提交、算子融合与 CUDA Graphs 减少跨界次数的方法,还有 purego、Wasm、纯 Go
重写与进程外服务等绕开 cgo 的做法;18.2 讨论阻塞的外部调用对调度器的影响:sysmon 如何取回停在 C 代码中的
P,并发的阻塞调用为何导致线程膨胀,外部线程回调 Go 时 extra M 的借用,以及用锁定线程的单一拥有者
goroutine 处理设备上下文的线程亲和性;18.3 讨论显存与 Go 堆的分界:设备地址为何不受指针规则约束,runtime.Pinner
与页锁定内存这两种「固定」的区别,异步传输为何需要把固定延长到传输完成之后,以及统一内存改变了什么、没有改变什么;18.4 讨论三种并行的关系:goroutine 的并发、GPU 的 SIMT 与 CPU 的
SIMD,流与事件如何与 goroutine 衔接,Go 1.27 实验性的 simd 包,以及判断一段计算是否值得交给 GPU 的依据。