跳转到内容

SoA 架构

Rinne 为极致吞吐量而生。虽然大多数 JavaScript 库使用 对象数组 (AoS) 存储数据,但 Rinne 内核采用了 结构体数组 (SoA) 布局。

const particles = [
{ x: 0, y: 0, z: 0 },
{ x: 1, y: 1, z: 1 }
];

在 AoS 中,属性分散在堆内存中。当 CPU 尝试更新 50,000 个粒子时,会面临频繁的 缓存失效 (Cache Miss)

结构体数组 (SoA - Structure of Arrays)

Section titled “结构体数组 (SoA - Structure of Arrays)”
const xBuffer = new Float64Array(50000);
const yBuffer = new Float64Array(50000);
const zBuffer = new Float64Array(50000);

Rinne 将属性存储在连续的 Float64Array 缓冲区中。这确保了当 CPU 处理一个粒子时,后续的几十个粒子的数据已经预加载到了 L1/L2 缓存中。

  • 零对象分配:Rinne 在 tick() 循环中不创建任何临时对象。
  • 内存局部性:顺序内存访问模式允许现代 CPU 高效执行预取。
  • SIMD 就绪:SoA 布局使得将来将计算卸载到 WebWorker 或使用 SIMD 指令变得极其简单。

在我们的压力测试中,Rinne 可以在标准 V8 引擎上以不到 1.3ms 的帧预算维持 50,000 个活跃节点