How this.thread.x Works in GPU.js 1D Kernels

In GPU.js, this.thread.x serves as the primary index locator when executing parallel operations across a single-dimensional data set. This article explains the mechanics of this.thread.x in a 1D kernel, contrasting it with traditional JavaScript loops, demonstrating how threads map directly to data indices, and providing a concise code implementation to illustrate its real-world function.

Understanding the Thread Coordinate System

GPU.js allows developers to write standard JavaScript functions and compile them into WebGL shaders that run on the GPU. Unlike a CPU that iterates through an array sequentially using a loop, the GPU executes the kernel function concurrently across hundreds or thousands of processing cores.

When you define an execution dimension using setOutput([size]), GPU.js spawns a grid of threads matching that size. In a one-dimensional kernel (defined with a single dimension such as setOutput([1000])), execution occurs along the X-axis.

Within this execution context:

Comparison: CPU Loop vs. 1D Kernel

To understand how this.thread.x functions, consider how a standard CPU handles array manipulation:

// CPU Approach (Sequential)
const size = 5;
const output = [];
for (let i = 0; i < size; i++) {
  output[i] = i * 2;
}

In the CPU example, a single thread executes five consecutive iterations, manually incrementing i from 0 to 4.

In GPU.js, the execution is distributed:

// GPU.js Approach (Parallel)
const gpu = new GPU();

const multiplyKernel = gpu.createKernel(function() {
  return this.thread.x * 2;
}).setOutput([5]);

const result = multiplyKernel(); 
// Output: Float32Array [0, 2, 4, 6, 8]

In this 1D kernel:

  1. Five distinct threads are initiated simultaneously.
  2. Thread 0 evaluates this.thread.x as 0 and returns 0.
  3. Thread 1 evaluates this.thread.x as 1 and returns 2.
  4. This continues concurrently through Thread 4, which returns 8.
  5. GPU.js aggregates the return values of all threads into the final 1D array based on their respective this.thread.x coordinates.

Working with Input Arrays

The this.thread.x variable is most commonly used to retrieve elements from input arrays that correspond to the thread's position.

const gpu = new GPU();

const addArrays = gpu.createKernel(function(a, b) {
  return a[this.thread.x] + b[this.thread.x];
}).setOutput([1024]);

const arrayA = new Float32Array(1024).fill(5);
const arrayB = new Float32Array(1024).fill(10);

const sum = addArrays(arrayA, arrayB);

In this implementation, each thread accesses the exact element in arrayA and arrayB that matches its this.thread.x index. Thread 512 accesses a[512] and b[512], performs the addition, and places the result at index 512 of the output array without interfering with any other thread.

Summary of 1D Behavior