Task 3 of 6
Here's the rule that shapes gpu.js kernels (and any fragment shader): a thread
can read anywhere but can only write one place — its own cell, via
return. There is no out[i + 1] = value here, because 4096
simultaneous writers into shared cells would be chaos (who wins? in what order?).
So the "push my value over there" plan — a scatter — must be turned inside out. Don't ask "where does my value go?"; ask "whose value lands in my cell?" — a gather. Try it on a rotation: every value moves one slot to the right, and the last wraps around to slot 0.
ring one slot to the right by gathering:
each thread pulls the value that belongs in its cell.i pulls from index i − 1If every value moves right by one, then the value in my cell came
from my left: index this.thread.x - 1. The starter currently
pulls from the right — that rotates the wrong way.
Adding n before the modulo keeps the index positive:
(this.thread.x - 1 + this.constants.n) % this.constants.n
That turns -1 into 63 and leaves 1…63 alone.
atomicAdd — serializes threads and costs
dearly. That's why GPU folklore compresses this lesson into four words:
turn scatter into gather.
This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.