Same GPU, same maths library, same missing +1 in a threadgroup stride. In llama.cpp it is worth a large multiple of prompt-processing speed and takes a real agent task down to about half its time. In stable-diffusion.cpp the identical kernel got 4× faster and the picture arrived in the same time — because a diffusion step spends most of its seconds where no matrix tile can reach.
Threadgroup memory is served in 32 banks of 4 bytes, cycling every 128 bytes. A dense float sA[BM][BK] with BK=64 puts one row every 256 bytes — a multiple of the cycle — so every lane reading sA[row][k] with the same k asks for the same bank and queues. Rows starting 65 floats apart spread across banks.
Both programs hit it, because both use ggml, and on this card ggml's own tiled GEMM is gated off (has_simdgroup_mm = false), so each wrote a tile by hand — and each wrote it dense.
In llama.cpp the same fix is worth several times the prompt-processing throughput, and it halves a real agent task — a file read, a tool call and an answer. That is a large enough result to stand on its own, so its measurements, its patch and its task are kept for a chapter rather than spent here.
What this post uses from it is only the shape: where the tile is the workload, it pays; where the tile is a guest, it does not. Everything measured below is stable-diffusion.cpp.


Identical, not “close”. A pure addressing change must produce this — and it is how you know a rebuild actually shipped.
So the tile touches less than half of a render, and inside that half it is evidently a small share. In llama.cpp the tile is the workload — which is the whole difference.
Four renders, same recipe, measured at the GPU rail: 5.23–5.27 Wh each, 80–84 s wall once weights are warm. The text side is a different currency: 66 s of your time per agent task.




threadgroup float * sB = shmem + BM*(BK + 1); sA[lm*(BK + 1) + lk] = v; sB[lk*(BN + 1) + ln] = v; const float a0 = sA[(2*thm + 0)*(BK + 1) + k]; const float b0 = sB[k*(BN + 1) + 2*thn + 0];
0003-simt-padding.py applies all eight to stable-diffusion.cpp, each anchored to an exact match. llama.cpp's version is the same idea with a 64×64 tile and a dequantising prologue.
It does not claim images got faster — they did not, and that is reported, not buried. It does claim one defect, two payoffs, measured on the same card: a 3.2× prefill where the tile is the workload, and 1.4% where it is a guest.