wip(assembler): round L7 -- shared column cache across workers: whole view 16-19% faster, world unchanged

SharedColumnCache.h: a world-owned, bounded 4-way second-tier cache of exact column values
(heightfield and floating islands), keyed by recipe/plan identity plus content hash, XY and island
id. Lock-free seqlock reads; set-local spin lock on misses. The FLazy thread-local tier stays
first. 83.6% of repeated column work was cross-worker; formula evaluations -60.9%.
W12 L1 view: Luna 2.165 -> 1.754 s; reviewer interleaved 2.059 -> 1.722 s. 8 m crossing new tiles
82 -> 52 ms. +66 MiB peak RSS. All hashes (whole view, per-LOD, exact queries, islands seed 0)
identical at W1/W8/W12, Clang off and GCC default. MSVC/UBT not compiled here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-19 21:46:15 +02:00
1 parent 9898e057fd
commit 4b1108bf86
12 files changed
+751 -92

No files matched your search

+54 -11
View File
@@ -5,6 +5,7 @@
#include "VoxelForgeCore/VoxelForgeCore.h"
#include <algorithm>
#include <atomic>
#include <bit>
#include <charconv>
#include <chrono>
@@ -121,6 +122,9 @@ WorldAssemblyFeatureColumnRangeV1 BuildWorldAssemblyFeatureColumnRangeV1(
namespace world_assembly_detail
{
using FSharedHeightfieldColumnCache =
VoxelForgeCoreShared::TSharedColumnValueCache<HeightfieldPointSample,131072,4>;
// Preserve recipe order without allocating or looking up metadata in the point loop.
// Garder l'ordre de recette sans allocation ni recherche de metadonnees par point.
struct FeatureRange
@@ -1375,6 +1379,9 @@ namespace world_assembly_detail
std::array<std::uint8_t, HeightfieldColumnCacheSetCount>> HeightfieldColumnCacheNextWay;
inline thread_local HeightfieldColumnCacheStats HeightfieldColumnStats{};
inline thread_local bool HeightfieldColumnCacheLegacyDirectMapped=false;
inline thread_local std::array<std::int64_t,4> HeightfieldColumnCaptureBounds{};
inline thread_local bool HeightfieldColumnCaptureBoundsValid=false;
inline std::atomic<std::uint64_t> HeightfieldColumnCaptureSequence{0};
inline std::size_t HeightfieldColumnCacheSet(const WorldAssemblyRecipeV1& recipe,
const WorldAssemblyStratumPlanV1& plan,std::int64_t x,std::int64_t y) noexcept
@@ -1587,22 +1594,46 @@ namespace world_assembly_detail
replacement=&cache[first+replacementWay];
}
auto& entry=*replacement;
const auto start=std::chrono::steady_clock::now();
HeightfieldPointSample column=EvaluateColumn(recipe,plan,x,y);
HeightfieldColumnStats.columnComputeMilliseconds+=std::chrono::duration<double,std::milli>(
std::chrono::steady_clock::now()-start).count();
++HeightfieldColumnStats.columnMisses;
if(HeightfieldColumnStats.captureCoordinates&&HeightfieldColumnStats.coordinateCaptureComplete)
const auto compute=[&]()
{
try
const std::uint64_t sequence=HeightfieldColumnStats.captureCoordinates
?HeightfieldColumnCaptureSequence.fetch_add(1,std::memory_order_relaxed):0;
const auto start=std::chrono::steady_clock::now();
HeightfieldPointSample result=EvaluateColumn(recipe,plan,x,y);
HeightfieldColumnStats.columnComputeMilliseconds+=std::chrono::duration<double,std::milli>(
std::chrono::steady_clock::now()-start).count();
++HeightfieldColumnStats.columnEvaluations;
if(HeightfieldColumnStats.captureCoordinates
&&HeightfieldColumnStats.coordinateCaptureComplete)
{
HeightfieldColumnStats.evaluatedCoordinates.push_back({x,y});
}
catch(...)
{
HeightfieldColumnStats.coordinateCaptureComplete=false;
try
{
const bool outside=HeightfieldColumnCaptureBoundsValid
&&(x<HeightfieldColumnCaptureBounds[0]||x>HeightfieldColumnCaptureBounds[2]
||y<HeightfieldColumnCaptureBounds[1]||y>HeightfieldColumnCaptureBounds[3]);
HeightfieldColumnStats.evaluatedCoordinates.push_back({x,y,sequence,outside});
}
catch(...)
{
HeightfieldColumnStats.coordinateCaptureComplete=false;
}
}
return result;
};
HeightfieldPointSample column{};
if(auto* shared=FSharedHeightfieldColumnCache::threadActive())
{
const VoxelForgeCoreShared::FColumnCacheKey key{
static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&recipe)),
recipe.contentHash,
static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&plan)),
plan.contentHash,x,y};
bool computed=false;
column=shared->getOrCompute(key,compute,computed);
if(!computed)++HeightfieldColumnStats.sharedColumnHits;
}
else column=compute();
entry={&recipe,&plan,recipe.contentHash,plan.contentHash,x,y,column};
return column;
}
@@ -2087,10 +2118,22 @@ void Heightfield2D::resetThreadColumnCacheStats(bool captureCoordinates, bool cl
Stats.columnHits=0;
Stats.columnMisses=0;
Stats.columnConflictMisses=0;
Stats.sharedColumnHits=0;
Stats.columnEvaluations=0;
Stats.columnComputeMilliseconds=0.0;
Stats.captureCoordinates=captureCoordinates;
Stats.coordinateCaptureComplete=true;
Stats.evaluatedCoordinates.clear();
world_assembly_detail::HeightfieldColumnCaptureBoundsValid=false;
}
void Heightfield2D::setThreadColumnCaptureBounds(std::int64_t minimumXSubvoxels,
std::int64_t minimumYSubvoxels,std::int64_t maximumXSubvoxels,
std::int64_t maximumYSubvoxels) noexcept
{
world_assembly_detail::HeightfieldColumnCaptureBounds={minimumXSubvoxels,
minimumYSubvoxels,maximumXSubvoxels,maximumYSubvoxels};
world_assembly_detail::HeightfieldColumnCaptureBoundsValid=true;
}
void Heightfield2D::setThreadColumnCacheLegacyDirectMapped(bool enabled) noexcept