MCPcopy Create free account
hub / github.com/FastLED/FastLED / runPerlinBenchmark

Function runPerlinBenchmark

examples/AutoResearch/AutoResearchAnimartrixBench.h:44–123  ·  view source on GitHub ↗

Sweep a 2D coordinate grid the same way an Animartrix render pass would (one Perlin lookup per output pixel). 16*16 = 256 pixels per outer iter, matching a 16x16 panel — small enough that the compiler won't unroll the world, large enough that any per-iteration fixed overhead is amortized.

Source from the content-addressed store, hash-verified

42// won't unroll the world, large enough that any per-iteration fixed
43// overhead is amortized.
44inline PerlinBenchResult runPerlinBenchmark(int iters) {
45 PerlinBenchResult r;
46 r.iterations = iters;
47
48 // Init the i16 implementation's fade lookup table once, off the
49 // benchmark clock. Function-local static so the linter's
50 // static-in-header rule stays happy and C++11's thread-safe init
51 // guarantees a single initialization across calls. The float path
52 // has no equivalent setup.
53 struct FadeLut {
54 int32_t table[257];
55 FadeLut() { fl::perlin_i16_optimized::init_fade_lut(table); }
56 };
57 static const FadeLut fade_lut_holder; // C++11 magic statics
58 const int32_t* fade_lut = fade_lut_holder.table;
59
60 constexpr int GRID = 16; // 16x16 pixel pass per iteration
61 constexpr float STEP_F = 0.05f; // Animartrix-typical pixel step in noise space
62 // Mirror in fixed-point: 0.05 in Q16.16 = 0.05 * 65536 ≈ 3277
63 constexpr int32_t STEP_I = static_cast<int32_t>(0.05f * 65536.0f);
64
65 // ── Float pnoise ──────────────────────────────────────────────
66 {
67 float ax = 0.0f, ay = 0.0f;
68 int32_t sink = 0;
69 uint32_t t0 = micros();
70 for (int it = 0; it < iters; it++) {
71 // Slowly drift the origin across the iter so the compiler
72 // can't pre-compute. Same pattern Animartrix uses (the
73 // origin advances with `time_speed * dt` each frame).
74 ax += 0.011f;
75 ay += 0.013f;
76 for (int row = 0; row < GRID; row++) {
77 float y = ay + row * STEP_F;
78 for (int col = 0; col < GRID; col++) {
79 float x = ax + col * STEP_F;
80 float n = fl::pnoise(x, y, 0.0f);
81 // Map [-1, 1] → int8 the way Animartrix's output
82 // stage does. Sink to defeat DCE.
83 sink += static_cast<int32_t>(n * 127.0f);
84 }
85 }
86 }
87 uint32_t t1 = micros();
88 g_animartrix_bench_sink = sink;
89 r.pnoise_float_us = static_cast<int64_t>(t1 - t0);
90 }
91
92 // ── i16 fixed-point pnoise2d ──────────────────────────────────
93 {
94 int32_t ax_i = 0, ay_i = 0;
95 // Q16.16 increment for the slow drift (matches 0.011, 0.013 in float)
96 constexpr int32_t DRIFT_X = static_cast<int32_t>(0.011f * 65536.0f);
97 constexpr int32_t DRIFT_Y = static_cast<int32_t>(0.013f * 65536.0f);
98 int32_t sink = 0;
99 uint32_t t0 = micros();
100 for (int it = 0; it < iters; it++) {
101 ax_i += DRIFT_X;

Callers 1

registerFunctionsMethod · 0.85

Calls 2

pnoiseFunction · 0.85
microsFunction · 0.50

Tested by

no test coverage detected