code wiki / (root) / nx_parallel.nx

nx_parallel.nx

buildroot/runtime/nx_parallel.nx

13103 B371 linesdepth 7pulls 9 transitivereach 5 importersview sourcekind tooltopic parallel
docsdependenciesstructsconstsfunctions

about

nx_parallel.nx -- parallel_for / parallel_map / parallel_reduce. Built on top of nx_thread_pool: each primitive partitions its iteration range into n_workers chunks and submits one task per chunk. Wait until pool.tasks_completed has advanced by n_chunks (snapshot-based, so multiple parallel_* calls compose). Why partition rather than per-iter-submit: * Per-iter submit pays ~20ns chan_send + dispatch per index; for cheap bodies (e.g. element-wise add) that dwarfs the work. Chunked submission amortises chan overhead across ~ITER_COUNT/n_workers items. Static even partition for MVP -- range is divided into roughly equal contiguous chunks. Dynamic / work-stealing partitioning is the L7-evolution follow-up once we measure imbalanced workloads suffering >5% throughput loss. Public API (single namespace; sealed strategy enum): nx_parallel_for(pool, begin, end, fn(i64)) nx_parallel_map_i64(pool, in_ptr, out_ptr, n, fn(i64) -> i64) nx_parallel_reduce_i64(pool, ptr, n, init, fn(i64, i64) -> i64) Composes against: [[nx_thread_pool_shared_queue]] (workers), [[vyukov_mpmc_channel]] (task queue), [[atomic_intrinsics_real_amo]] (per-chunk reduction sum), [[nx_hw_dynamic_probes]] (chunk count defaults to nx_hw_worker_count).

dependencies 4 imports · 5 importers

nx_syscalls.nx nx_atom.nx nx_thread_pool.nx nx_hw.nx nx_parallel.nx nx_dot_simd_demo.nx nx_parallel_simd_reduce.nx nx_parallel_test.nx nx_pardemo_heavy.nx nx_sum_bench_all.nx

imports: nx_syscalls.nxnx_atom.nxnx_thread_pool.nxnx_hw.nx

imported by: nx_dot_simd_demo.nxnx_parallel_simd_reduce.nxnx_parallel_test.nxnx_pardemo_heavy.nxnx_sum_bench_all.nx

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main nx_pool_new nx_hw_worker_count nx_hw_cpu_count sys_mmap sys_munmap sys_mmap ↻ nx_chan_new sys_mmap ↻ _nx_chan_cell sys_thread_create nx_thread_spawn sys_mmap ↻ nx_thread_spawn_fn sys_mmap ↻ nx_parallel_for sys_mmap ↻ nx_atom_load_i64 _nx_chunk_start _nx_chunk_end nx_pool_submit nx_atom_faa_i64 nx_chan_send nx_chan_try_send _nx_chan_cell ↻ nx_thread_yield _pool_futex_wake_all sys_futex_wake sys_mmap ↻ nx_parallel_map_i64 sys_mmap ↻ nx_atom_load_i64 ↻ _nx_chunk_start ↻ _nx_chunk_end ↻ nx_pool_submit ↻ nx_parallel_reduce_i64 sys_mmap ↻ nx_atom_load_i64 ↻ _nx_chunk_start ↻ _nx_chunk_end ↻

structs

40struct NxPfChunk
48struct NxMapChunk
58struct NxReduceChunk

consts

46const NX_PF_CHUNK_BYTES: i64 = 24
56const NX_MAP_CHUNK_BYTES: i64 = 40
67const NX_REDUCE_CHUNK_BYTES: i64 = 48

functions

70func _nx_pf_worker(ctx: i64) -> i64
82func _nx_map_worker(ctx: i64) -> i64
98func _nx_reduce_worker(ctx: i64) -> i64
116func _nx_chunk_start(begin: i64, end: i64, n_chunks: i64, idx: i64) -> i64
122func _nx_chunk_end(begin: i64, end: i64, n_chunks: i64, idx: i64) -> i64
132func nx_parallel_for(pool: *NxThreadPool, begin: i64, end: i64,
168func nx_parallel_map_i64(pool: *NxThreadPool, in_ptr: *i64, out_ptr: *i64,
206func nx_parallel_reduce_i64(pool: *NxThreadPool, arr_ptr: *i64, n: i64,
258func _nx_reduce_worker_simd_sum(ctx: i64) -> i64
288func nx_parallel_reduce_sum_simd_i64(pool: *NxThreadPool, arr_ptr: *i64,
337func _pf_self_test_noop(i: i64) -> i64 { return i + 1 }
338func _map_self_test_double(x: i64) -> i64 { return x * 2 }
339func _reduce_self_test_add(a: i64, b: i64) -> i64 { return a + b }
341func main() -> i64