Let me start with the basics. People keep saying memory access should be coalesced and free of bank conflicts. Are those the same thing?
先问个最基础的:大家老说访存要 coalesce、要避开 bank conflict,这俩是一回事吗?
No, but they ask the same question: when the 32 threads of a warp access memory together, how are their addresses laid out?
不是一回事,但问的是同一个问题:一个 warp 的 32 个线程同时访存时,地址是怎么分布的。
Why does it always come down to the warp?
为什么偏偏按 warp 来看?
Because a warp's 32 threads are the batch that issues memory requests together. That batch of addresses is what the hardware looks at.
因为一个 warp 的 32 个线程是同时发访存请求的那一批,硬件看的就是这一批地址长什么样。
Start with coalescing, then.
那先说 coalesce。
Coalescing is about global memory. When 32 threads read 128 consecutive bytes, the reads merge into one transfer. When the addresses are scattered, say each thread one row apart, they split into as many as 32 transfers.
coalesce 说的是 global memory。32 个线程读连续的 128 字节,能合并成一次传输;地址要是散的,比如每个线程隔一行读一个,最多会拆成 32 次传输。
And bank conflicts?
bank conflict 呢?
Those are about shared memory. It is split into 32 banks, each 4 bytes wide; the n-th 4-byte word lives in bank n % 32, and each bank can serve one address per cycle. If the 32 threads hit 32 different banks, the read finishes in one pass. If several threads hit different addresses in the same bank, they queue up, up to 32 times slower. If they all read the same address, that is a broadcast, which is fine.
说的是 shared memory。它分成 32 个 bank,每个 bank 4 字节宽,第 n 个 4 字节落在 bank n % 32,一个周期里每个 bank 只能服务一个地址。32 个线程落在 32 个不同的 bank,一次完成;多个线程读同一个 bank 的不同地址,就要排队,最坏慢 32 倍;大家都读同一个地址是广播,没问题。