我查看了编程指南和最佳实践指南,其中提到全局内存访问需要 400-600 个周期。我没有看到太多其他内存类型,如纹理缓存、常量缓存、共享内存。寄存器的内存延迟为 0。
如果所有线程在常量缓存中使用相同的地址,我认为常量缓存与寄存器相同。最坏的情况我不太确定。
只要没有银行冲突,共享内存就和寄存器一样?如果有,那么延迟如何展开?
纹理缓存呢?
For (Kepler) Tesla K20 the latencies are as follows:
Global memory: 440 clocks
Constant memory
L1: 48 clocks
L2: 120 clocks
Shared memory: 48 clocks
Texture memory
L1: 108 clocks
L2: 240 clocks
How do I know? I ran the microbenchmarks described by the authors of Demystifying GPU Microarchitecture through Microbenchmarking. They provide similar results for the older GTX 280.
This was measured on a Linux cluster, the computing node where I was running the benchmarks was not used by any other users or ran any other processes. It is BULLX linux with a pair of 8 core Xeons and 64 GB RAM, nvcc 6.5.12. I changed the sm_20
to sm_35
for compiling.
There is also an operands cost chapter in PTX ISA although it is not very helpful, it just reiterates what you already expect, without giving precise figures.
共享/常量/纹理内存的延迟很小,取决于您拥有的设备。一般来说,尽管 GPU 被设计为吞吐量架构,这意味着通过创建足够多的线程可以隐藏内存(包括全局内存)的延迟。
指南谈论全局内存延迟的原因是延迟比其他内存高几个数量级,这意味着它是要考虑优化的主要延迟。
您特别提到了常量缓存。你是非常正确的,如果一个warp(即32个线程组)中的所有线程访问相同的地址,那么就没有惩罚,即从缓存中读取值并同时广播到所有线程。但是,如果线程访问不同的地址,则访问必须序列化,因为缓存一次只能提供一个值。如果您使用的是 CUDA Profiler,那么这将显示在序列化计数器下。
与常量缓存不同,共享内存可以提供更高的带宽。查看CUDA 优化讲座,了解更多细节以及银行冲突及其影响的解释。