GPU 编程的 io 瓶颈如何解决？
简单回答的话：

1. 尽可能减少不必要的访存操作。因为通常来说，访存的操作比计算慢两个数量级，所以通过一些简单计算可以得到的值，算出来可能比查出来快。

2. 注意内存上数据的组织方式。一个是要按照GPU当中的线程块大小组织，并且保证相邻线程要访问的数据在内存上也邻接；另一方面要注意GPU高速缓存线的地址对齐要求，以及缓存线的大小，尽可能填充完整的缓存线。

3. 注意数据的宽度和交织模式。比如对于一个含有3个分量的向量，其实在很多GPU上面都是按照4分量的方式去访存的。有的时候索性使用4分量反而会有更好的缓存线效率（视硬件和编译器策略而异）

4. 由于近代GPU当中单线程对于向量的访问其实是标量化的，有的时候将向量的各个分量分开组织到不同的缓冲区反而会更快，缓存效率更高（视具体硬件而异）

5. 如果ALU的余量比较大，且GPU当中工作量的占有率不高，可以考虑安排其他并行任务或者设法提高工作量的并行度，通过在不同的线程块之间切换隐藏访存延迟。

6. 充分利用片上存储空间（LDS），线程间交换数据结果尽可能地走片上空间或者高速缓存，尽量避免中间结果的写存（回刷主存）操作。

7. 开启GPU硬件提供的各种带宽压缩技术。对于稀疏数据存储采用更小带宽的存储方式，用计算换带宽。

8. 利用GPU硬件提供的intrinsic宏，实现线程间数据的简单交换或者共享，减少访存操作。

9. 调整线程组（thread group）的大小，使其在特定GPU上能够更好地被调度。（具体尺寸需要参考具体硬件的执行器大小和执行方式）

10. 对于纯粹的数据缓冲区访问，使用GPU的非贴图访存指令（裸访存指令），避免贴图单元的过滤功能带来的额外开销。（通常妥善指定缓冲区类型即可，编译器会自动处理。注意关闭各向异性等不需要的功能）

11. 对于精度要求不高的情况尽可能使用更小的数据类型。不过在一些硬件（特别是N卡）上有的时候没有任何效果。