GPUFlightAll performance labs

Shared Memory Banks: Eliminate a 32-Way Conflict

Each lane reads a different shared-memory word, but the starter spaces those words 32 apart. For 32-bit values, bank = word index mod 32, so all 32 addresses land in one bank and the warp request is serialized. Remap each warp to 32 adjacent words so lane 0 uses bank 0, lane 1 uses bank 1, and so on.

Sign in to run this lab. GPU availability and credits are shown in the app.

Languages: CUDA C++, Rust

Lesson

Shared memory is divided into 32 banks, and each bank can normally serve one 32-bit word per warp request. Consecutive words rotate through consecutive banks. A stride of 32 words wraps the bank index back to the same bank, so lane 0 reading word 0, lane 1 reading word 32, and lane 2 reading word 64 creates distinct addresses in bank 0. The hardware services those addresses as extra wavefronts instead of one parallel request. GPUFlight reports that cost as average N-way serialization: 1.00x is conflict-free and a deliberate stride-32 pattern approaches 32x.

A same-address read broadcast differs from different addresses mapping to the same bank. Preserve partial-warp checks, then apply the mapping to the transpose padding sequel.

What you will learn

  • Calculate a 32-bit shared-memory word's bank with wordIndex mod 32.
  • Distinguish a same-address broadcast from different addresses colliding in one bank.
  • Lay out each warp's values contiguously so adjacent lanes use adjacent banks.
  • Interpret GPUFlight's shared-memory N-way metric, where 1.00x is conflict-free.

Starter code

    extern __shared__ volatile float tile[];

    int tid = threadIdx.x;
    int i = blockIdx.x * blockDim.x + tid;
    int lane = tid & 31;
    int warp = tid >> 5;

    // Every lane uses a distinct word, but a 32-word stride maps all of them
    // to the same bank: (lane * 32) mod 32 = 0.
    int sharedIndex = warp * 1024 + lane * 32;
    tile[sharedIndex] = static_cast<float>(lane + 1);
    __syncthreads();

    float sum = 0.0f;
    for (int repeat = 0; repeat < 256; ++repeat) {
        sum += tile[sharedIndex];
    }
    if (i < N) output[i] = sum;

Sign in to run