Task 3 of 4

Two Machines, Two Answers

JavaScript numbers are 64-bit floats — about 16 significant digits. GPU shaders compute in 32-bit floats — about 7. Run the same arithmetic on both machines and the answers drift apart, a little more with every operation.

The kernel below adds 1,000 fractions per thread; a plain JavaScript loop computes the identical sum in float64. The two results will disagree somewhere around the sixth decimal place — which means === is the wrong question. The right question is: are they within a tolerance that matters for your problem?

Goal: finish the kernel — each thread sums 1 / (k + this.thread.x) for k = 1…1000 — then fix the final comparison to use a tolerance instead of ===.

Requirements

Hint 1 — loops inside kernels

Fixed-bound loops are fine in kernel code:

for (let k = 1; k <= 1000; k++) {
  sum += 1 / (k + this.thread.x);
}
Hint 2 — the tolerant verdict

Replace the === comparison in the last line with Math.abs(result[0] - ref) < 1e-3. Exact equality across float32 and float64 is a coin you will almost never win.

Same idea elsewhere

float32-by-default is universal shader behavior — and production GPU code often trades away more precision on purpose: CUDA's --use_fast_math, TF32 on tensor cores, half-precision inference. That's why numerical toolkits ship allclose-style comparisons, and why this course's tests use assertClose instead of ==.

All tasks in Measuring Speed Honestly

  1. The First Call Is a Lie
  2. Pay the Transfer Tax
  3. Two Machines, Two Answers
  4. When the CPU Wins

This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.