Chronix

Compute Engine & SIMD

Time-series analytics involves repetitive numerical operations over large arrays — summing millions of floats, comparing timestamps, filtering by tag values. Modern CPUs provide SIMD (Single….

On this page

Motivation

Time-series analytics involves repetitive numerical operations over large arrays — summing millions of floats, comparing timestamps, filtering by tag values. Modern CPUs provide SIMD (Single Instruction, Multiple Data) instructions that process 4–16 values simultaneously.

SIMD Instruction Sets

ISARegister Widthf64 per OpAvailability
SSE2128-bit2All x86-64
AVX2256-bit4Intel Haswell+ (2013)
AVX-512512-bit8Intel Skylake-X+ (2017)
NEON128-bit2All ARM64

Chronix auto-detects the available ISA at startup and dispatches to the widest supported implementation.

Vectorized Operations

Aggregation

Scalar sum of n floats requires n additions (latency-bound by data dependencies). SIMD sum uses k accumulators in parallel:

Scalar:   a₁ + a₂ + a₃ + a₄ + a₅ + a₆ + a₇ + a₈  = 8 ops

AVX2:     [a₁ a₂ a₃ a₄] + [a₅ a₆ a₇ a₈]  = 1 vector op
          horizontal sum of result          = 3 ops
          Total: 4 ops (2× fewer)

For large arrays, the speedup approaches k× where k is the SIMD width in elements.

Filtering

Timestamp range checks can be vectorized:

Scalar:  for each ts: if ts >= start && ts <= end → emit

AVX2:    compare 4 timestamps simultaneously
         pack matching indices
         gather matching values

Arrow Integration

Apache Arrow's columnar layout is SIMD-friendly by design — values are stored in contiguous, aligned arrays. The compute kernels in chronix_analytics::compute operate directly on Arrow arrays without copying.

Kernel Catalog

chronix_analytics::compute::simd, all over &[f64] or &[i64] with a scalar fallback:

KernelOperation
simd_sumSum
simd_meanArithmetic mean
simd_varianceVariance about a supplied mean (sample, n − 1)
simd_population_varianceVariance about a supplied mean (n)
simd_mean_varianceBoth, in one pass
simd_std_devStandard deviation
simd_min_maxMinimum and maximum, in one pass
simd_range_filter_i64Indices of timestamps inside [min, max]
simd_dot_productDot product — the correlation and regression helper
simd_tierWhich instruction set was selected at runtime

CpuEngine::batch_z_score sits above them: one simd_mean_variance pass over the whole input, then the per-element score.

The column codecs — Gorilla's XOR, delta-of-delta, PFOR — live in chronix-encoding, not here.

Why there is no GPU backend

A wgpu/WGSL compute backend was built and then deleted, and the reasoning is worth keeping because it is the kind of feature that gets re-proposed.

Exponential smoothing — the workload it was meant to accelerate — is inherently sequential: each smoothed value depends on the previous one, so the shader ran at workgroup_size(1) and used one lane of the device. The operations that do parallelise cleanly were not the bottleneck in any measured profile. What remained was a large dependency tree, a driver-compatibility surface, and a second code path to audit, in exchange for a benchmark line.

The SIMD tiers below stay, and NEON is the tier that matters most in practice: the primary deployment target is a 64-bit ARM gateway.

Benchmarking

Chronix includes micro-benchmarks for all compute kernels:

cargo bench --package chronix-analytics

Results include throughput in GB/s and elements/second, enabling comparison across hardware platforms.

Fallback Strategy

Runtime dispatch:
  ├── AVX-512 available?  → use 512-bit kernels
  ├── AVX2 available?     → use 256-bit kernels
  ├── NEON available?     → use 128-bit kernels (ARM)
  └── fallback            → scalar implementation

All SIMD kernels have a scalar fallback, ensuring correctness on any platform. The scalar path uses auto-vectorization hints (#[inline], loop structure) to enable compiler-generated SIMD where possible.

Improve this page on GitHub