memlnaut-nisps/nisps/core/perf.hpp
w1n5t0n 4f60fc8405 feat: nisps/core foundation — perf, types, concepts, buffers, rng, math
Greenfield C++20 core for the unified firmware+WASM rewrite (architecture.md
streams, meml-dn7). Header-only, platform-agnostic, no heap, no virtual
dispatch.

Components:
- perf.hpp        memory section + inlining macros, RP2040/RP2350-aware,
                  inert on host/Emscripten
- types.hpp       stereosample_t (mirrors firmware AudioDriver API),
                  sample_t/param_t aliases, DriverConfig negotiation struct
- concepts.hpp    MLEngine, AudioEngine, Mode (architecture §4.1-4.3)
- fixed_buffer.hpp  std::array-backed cursor; replaces std::vector in hot paths
- ring_buffer.hpp   SPSC lock-free FIFO, power-of-two capacity, atomic
                    head/tail; replaces pico/util/queue in core
- rng.hpp         xoshiro256+ with splitmix64 seeding, uniform/signed/
                  gaussian-via-3-uniforms (matches legacy MoveWeights shape)
- math.hpp        clamp01, fast_sigmoid (tanh-Padé, ~1.2% max err on [-6,6]),
                  exact_sigmoid, fast_exp, named Curve catalog (linear/exp/
                  log/square/sqrt/sigmoid/cubic) — TypeScript twin lives in
                  playground/src/output/curves.ts (stream 5)

Performance discipline (Chris's rules):
- No heap, no std::vector, no malloc/new in core
- All float literals carry .f suffix
- Memory section attrs syntactically present, inert on non-firmware builds
2026-04-29 15:21:52 +03:00

28 lines
1.1 KiB
C++

// nisps/core/perf.hpp — RP2040/RP2350 memory section + inlining attributes.
//
// On firmware builds the macros expand to GCC/Pico-specific section attributes
// so hot code/data lives in SRAM instead of XIP flash. On every other build
// (host tests, Emscripten/WASM) they are inert — the discipline of marking
// audio-critical declarations is preserved syntactically without affecting
// codegen.
//
// See architecture.md §3.4.
#pragma once
#if defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_RP2350)
// Pico SDK provides __not_in_flash and __not_in_flash_func.
// __not_in_flash takes a section name string; __not_in_flash_func wraps the
// declaration directly.
#define NISPS_AUDIO_MEM __not_in_flash("audio")
#define NISPS_AUDIO_FUNC __not_in_flash_func
#define NISPS_APP_SRAM __not_in_flash("app")
#define NISPS_FORCE_INLINE __attribute__((always_inline)) inline
#define NISPS_HOT __attribute__((hot))
#else
#define NISPS_AUDIO_MEM
#define NISPS_AUDIO_FUNC(decl) decl
#define NISPS_APP_SRAM
#define NISPS_FORCE_INLINE inline
#define NISPS_HOT
#endif