wip(l62): shared boundary-sample cache + hidden skirt skip -- PARKED: SW +8.5%, moving p50 +119..265%, full tier incomplete

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-26 09:47:58 +01:00
1 parent 135957831b
commit 6ae5c4460d
12 files changed
+705 -111

No files matched your search

@@ -54,12 +54,36 @@ namespace VoxelForgeCoreShared
}
};
// Exact identity for one world-lattice density sample. Unlike a column key this includes
// Z, sampling settings, and the edit generation; all coordinates remain explicit words.
struct FDensitySampleCacheKey
{
std::uint64_t fieldIdentity = 0;
std::uint64_t fieldGeneration = 0;
std::uint64_t editSequence = 0;
std::uint32_t lod = 0;
std::uint32_t step = 1;
std::uint32_t octaveDrop = 0;
std::int64_t interpolationStride = 0;
std::int64_t x = 0, y = 0, z = 0;
std::uint64_t queryContextLow = 0, queryContextHigh = 0;
std::array<std::uint64_t, 12> words() const noexcept
{
return {fieldIdentity, fieldGeneration, editSequence, lod, step, octaveDrop,
static_cast<std::uint64_t>(interpolationStride), static_cast<std::uint64_t>(x),
static_cast<std::uint64_t>(y), static_cast<std::uint64_t>(z),
queryContextLow, queryContextHigh};
}
};
// A bounded, world-owned second-level cache. Existing thread-local caches stay first, so
// their ordinary hit path remains private and lock-free. Shared hits read atomic words; only
// a shared miss takes the set spin lock. Entries are four-way set associative, evict on
// collision, and carry pointer identities plus content hashes to reject stale reuse.
// Les caches TLS restent le premier niveau; seul un defaut partage prend le verrou du groupe.
template <typename TValue, std::size_t SetCount, std::size_t Ways = 4>
template <typename TValue, std::size_t SetCount, std::size_t Ways = 4,
typename TKey = FColumnCacheKey>
class TSharedColumnValueCache
{
static_assert(SetCount > 0 && (SetCount & (SetCount - 1)) == 0,
@@ -69,14 +93,14 @@ namespace VoxelForgeCoreShared
"shared column values must be trivially copyable");
static constexpr std::size_t ValueWordCount = (sizeof(TValue) + 7) / 8;
using FKeyWords = std::array<std::uint64_t, 7>;
using FKeyWords = decltype(std::declval<TKey>().words());
using FValueWords = std::array<std::uint64_t, ValueWordCount>;
struct FEntry
{
std::atomic<std::uint64_t> Version{0};
std::atomic<std::uint64_t> Tag{0};
std::array<std::atomic<std::uint64_t>, 7> Key{};
std::array<std::atomic<std::uint64_t>, FKeyWords{}.size()> Key{};
std::array<std::atomic<std::uint64_t>, ValueWordCount> Value{};
};
@@ -128,7 +152,7 @@ namespace VoxelForgeCoreShared
static TSharedColumnValueCache* threadActive() noexcept { return Active; }
template <typename TFactory>
TValue getOrCompute(const FColumnCacheKey& key, TFactory&& factory,
TValue getOrCompute(const TKey& key, TFactory&& factory,
bool& computed, FColumnCacheMetrics* metrics = nullptr)
{
computed = false;
@@ -139,6 +139,10 @@ namespace VoxelForgeCore
std::uint64_t columnCacheConflictMisses = 0;
std::uint64_t sharedColumnCacheHits = 0;
std::uint64_t columnEvaluations = 0;
std::uint64_t densitySampleCacheHits = 0;
std::uint64_t densitySampleCacheComputes = 0;
std::uint64_t marchingCubesSkirtTrianglesEmitted = 0;
std::uint64_t marchingCubesSkirtTriangleSeedsSkipped = 0;
std::uint64_t islandLocalCacheHits = 0;
std::uint64_t islandLocalCacheMisses = 0;
std::uint64_t islandLocalCacheConflictReplacements = 0;
@@ -719,8 +723,42 @@ namespace VoxelForgeCore
// Hors du domaine prepare, revenir au parcours complet canonique.
std::array<std::int64_t, 3> minimumSubvoxels{};
std::array<std::int64_t, 3> maximumSubvoxels{};
// Stable semantic identity used by the exact shared density-sample cache.
std::uint64_t densityCacheContextLow = 0;
std::uint64_t densityCacheContextHigh = 0;
};
inline void FinalizeWorldAssemblyFeatureTileListDensityContextV1(
WorldAssemblyFeatureTileListV1& list) noexcept
{
std::uint64_t low = 0x243f6a8885a308d3ull;
std::uint64_t high = 0x13198a2e03707344ull;
const auto add = [&](std::uint64_t value)
{
low ^= value + 0x9e3779b97f4a7c15ull + (low << 6) + (low >> 2);
low *= 0xbf58476d1ce4e5b9ull;
high ^= value + 0x94d049bb133111ebull + (high << 7) + (high >> 3);
high *= 0x9e3779b185ebca87ull;
};
add(list.featureIndices.size());
for (const auto value : list.featureIndices) add(value);
add(list.groupBounds.size());
for (const auto& group : list.groupBounds)
{
for (auto value : group.minimumSubvoxels) add(static_cast<std::uint64_t>(value));
for (auto value : group.maximumSubvoxels) add(static_cast<std::uint64_t>(value));
}
add(list.groupSearchOrder.size());
for (const auto value : list.groupSearchOrder) add(value);
add(list.groupDistanceLowerBoundsSubvoxels.size());
for (const auto value : list.groupDistanceLowerBoundsSubvoxels)
add(static_cast<std::uint64_t>(value));
add(list.groupSearchComplete ? 1u : 0u);
add(list.candidateEvaluationUseful ? 1u : 0u);
list.densityCacheContextLow = low;
list.densityCacheContextHigh = high;
}
using FloatingIslandTileFeatureListV1 = WorldAssemblyFeatureTileListV1;
using FloatingIslandFeatureGroupBoundsV1 = WorldAssemblyFeatureGroupBoundsV1;
@@ -743,10 +781,13 @@ namespace VoxelForgeCore
ScopedWorldAssemblyFeatureQueriesV1& operator=(const ScopedWorldAssemblyFeatureQueriesV1&) = delete;
static const WorldAssemblyFeatureTileListV1* find(const void* recipe, const void* plan,
std::int64_t x, std::int64_t y, std::int64_t z, bool columnOnly = false) noexcept;
static std::array<std::uint64_t, 2> densityCacheContext(
std::int64_t x, std::int64_t y, std::int64_t z) noexcept;
private:
std::span<const WorldAssemblyFeatureQueryV1> queries_;
bool forceCandidates_ = false;
const ScopedWorldAssemblyFeatureQueriesV1* previous_ = nullptr;
std::uint64_t densityCacheContextLow_ = 0, densityCacheContextHigh_ = 0;
};
struct VFCORE_API FloatingIslandManifestV1
@@ -1343,6 +1384,8 @@ namespace VoxelForgeCore
std::uint64_t columnConflictMisses = 0;
std::uint64_t sharedColumnHits = 0;
std::uint64_t columnEvaluations = 0;
std::uint64_t densitySampleCacheHits = 0;
std::uint64_t densitySampleCacheComputes = 0;
double columnComputeMilliseconds = 0.0;
bool captureCoordinates = false;
bool coordinateCaptureComplete = true;
@@ -1741,6 +1784,9 @@ namespace VoxelForgeCore
// Diagnostic seulement; enregistre les colonnes XY evaluees par cette tuile LOD8.
bool captureColumnCoordinates = false;
bool useSharedColumnCache = true;
// Fixed visibility mask for the four horizontal skirts and the two vertical cap skirts.
// The mask is part of the standalone mesh-cache identity and defaults to all faces.
std::uint8_t visibleSkirtFaceMask = 0x3f;
// Separate cold pass only; samples the MC inner stages without changing output.
// Passe froide separee seulement; mesure les etapes internes MC sans changer la sortie.
bool profileMesherStages = false;
@@ -2325,7 +2325,8 @@ FloatingIslandTileFeatureListV1 FloatingIslandFieldV1::buildFeatureTileList(
result.candidateEvaluationUseful=plan_->islands.size()>4;
result.minimumSubvoxels = tileMinimumSubvoxels;
result.maximumSubvoxels = tileMaximumSubvoxels;
if (!isValid()) return result;
if (!isValid())
{ FinalizeWorldAssemblyFeatureTileListDensityContextV1(result); return result; }
const auto features = solidSupportBounds();
result.featureIndices = BuildWorldAssemblyFeatureTileListV1(features,
@@ -2347,7 +2348,8 @@ FloatingIslandTileFeatureListV1 FloatingIslandFieldV1::buildFeatureTileList(
{
const auto source = findSourceIsland(edge);
if (source == plan_->islands.end())
{ result.groupBounds.clear(); result.featureIndices.clear(); return result; }
{ result.groupBounds.clear(); result.featureIndices.clear();
FinalizeWorldAssemblyFeatureTileListDensityContextV1(result); return result; }
auto& group = result.groupBounds[static_cast<std::size_t>(source - plan_->islands.begin())];
for (std::size_t axis = 0; axis < 3; ++axis)
{
@@ -2438,10 +2440,12 @@ FloatingIslandTileFeatureListV1 FloatingIslandFieldV1::buildFeatureTileList(
{
const std::size_t edgeIndex = static_cast<std::size_t>(featureIndex) - islandCount;
if (edgeIndex >= plan_->clusterEdges.size())
{ result.groupBounds.clear(); result.featureIndices.clear(); return result; }
{ result.groupBounds.clear(); result.featureIndices.clear();
FinalizeWorldAssemblyFeatureTileListDensityContextV1(result); return result; }
const auto source = findSourceIsland(plan_->clusterEdges[edgeIndex]);
if (source == plan_->islands.end())
{ result.groupBounds.clear(); result.featureIndices.clear(); return result; }
{ result.groupBounds.clear(); result.featureIndices.clear();
FinalizeWorldAssemblyFeatureTileListDensityContextV1(result); return result; }
selectedGroups[static_cast<std::size_t>(source - plan_->islands.begin())] = 1;
}
}
@@ -2464,6 +2468,7 @@ FloatingIslandTileFeatureListV1 FloatingIslandFieldV1::buildFeatureTileList(
if (plan_->clusterEdges[edgeIndex].fromIslandId == plan_->islands[islandIndex].stableId)
insertSorted(static_cast<std::uint32_t>(islandCount + edgeIndex));
}
FinalizeWorldAssemblyFeatureTileListDensityContextV1(result);
return result;
}
+40
View File
@@ -208,6 +208,7 @@ public:
routeFeatureOverlap_=true;
}
}
buildDensityCacheContext();
ActivePassageTileQueries=this;
}
~FScopedPassageTileQueries(){ActivePassageTileQueries=previous_;}
@@ -240,8 +241,46 @@ public:
bool hasCavernCandidates() const{return !cavernFeatureIndices_.empty();}
const std::vector<std::uint32_t>& cavernFeatureCandidates() const
{return cavernFeatureIndices_;}
static std::array<std::uint64_t,2> densityCacheContext(
const FStandaloneShapeWorld& shape) noexcept
{
const auto* queries=ActivePassageTileQueries;
if(!queries||!queries->matches(shape))return {};
return {queries->densityCacheContextLow_,queries->densityCacheContextHigh_};
}
private:
void buildDensityCacheContext() noexcept
{
std::uint64_t low=0x3c6ef372fe94f82bull;
std::uint64_t high=0xa54ff53a5f1d36f1ull;
const auto add=[&](std::uint64_t value)
{
low^=value+0x9e3779b97f4a7c15ull+(low<<6)+(low>>2);
low*=0xbf58476d1ce4e5b9ull;
high^=value+0x94d049bb133111ebull+(high<<7)+(high>>3);
high*=0x9e3779b185ebca87ull;
};
add(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(shape_)));
const auto addIndices=[&](const std::vector<std::uint32_t>& values)
{
add(values.size());
for(const auto value:values)add(value);
};
addIndices(featureIndices_);
addIndices(stampIndices_);
addIndices(cavernFeatureIndices_);
for(const auto value:passageRoutes_)add(value);
for(const auto value:passageColumns_)add(value);
for(const auto value:passageMouthSupports_)add(value);
add(routeFeatureOverlap_?1u:0u);
add(columnZOverlap_?1u:0u);
add(mayContainResolvedBoundaryBand_?1u:0u);
add(mayContainTransitionPassageFade_?1u:0u);
densityCacheContextLow_=low;
densityCacheContextHigh_=high;
}
const FStandaloneShapeWorld* shape_;
std::array<std::int64_t,3> minimumSubvoxels_,maximumSubvoxels_;
std::vector<std::uint32_t> featureIndices_;
@@ -251,6 +290,7 @@ public:
bool routeFeatureOverlap_=false,columnZOverlap_=false;
bool mayContainResolvedBoundaryBand_=true;
bool mayContainTransitionPassageFade_=true;
std::uint64_t densityCacheContextLow_=0,densityCacheContextHigh_=0;
const FScopedPassageTileQueries* previous_;
};
+49 -1
View File
@@ -1041,6 +1041,8 @@ namespace VoxelForgeCore
std::atomic<bool> shapeReady{false};
std::unique_ptr<world_assembly_detail::FSharedHeightfieldColumnCache>
sharedHeightfieldColumns;
std::unique_ptr<world_assembly_detail::FSharedDensitySampleCache>
sharedDensitySamples;
std::unique_ptr<floating_island_detail::FSharedIslandColumnCache>
sharedIslandColumns;
ShapeBuildRequest buildRequest;
@@ -1090,6 +1092,8 @@ namespace VoxelForgeCore
impl_->worldAssembly=snapshot.data_->worldAssembly;
impl_->resolvedLayout=snapshot.data_->resolvedLayout;
impl_->configuration=snapshot.data_->configuration;
impl_->sharedDensitySamples=
std::make_unique<world_assembly_detail::FSharedDensitySampleCache>();
if(impl_->worldAssembly)
{
if(!impl_->worldAssembly->plan.strates.empty())
@@ -2051,6 +2055,7 @@ namespace VoxelForgeCore
mesher.bStandaloneProofBlockCells=static_cast<int32>(std::clamp<std::uint32_t>(
options.proofBlockCells,1u,static_cast<std::uint32_t>(std::max(1,CHUNK_SIZE))));
mesher.bGenerateSkirts=world.bGenerateSkirts;
mesher.SetVisibleSkirtFaceMask(options.visibleSkirtFaceMask);
mesher.SkirtCells=static_cast<float>(world.SkirtCells)
*static_cast<float>(world.OwnerVoxelSizeMicrons)
/static_cast<float>(world.CoreVoxelSizeMicrons);
@@ -2157,6 +2162,42 @@ namespace VoxelForgeCore
MeshCells=FMath::Max(1,cells/Stride);
MeshStep=FMath::Max(1,extent/MeshCells);
}
if(!bNativeOnly&&options.useSharedColumnCache&&impl_->sharedDensitySamples)
{
mesher.SetSharedDensitySampleCache(impl_->sharedDensitySamples.get(),
[](void* Cache,const FStandaloneShapeWorld* ShapeWorld,uint64 FieldGeneration,
uint64 EditSequence,int32 Lod,int32 Step,int32 X,int32 Y,int32 Z,
bool& OutComputed)->float
{
VoxelForgeCoreShared::FDensitySampleCacheKey Key;
Key.fieldIdentity=static_cast<uint64>(reinterpret_cast<std::uintptr_t>(ShapeWorld));
Key.fieldGeneration=FieldGeneration;Key.editSequence=EditSequence;
Key.lod=static_cast<uint32>(Lod);Key.step=static_cast<uint32>(Step);
Key.octaveDrop=Heightfield2D::threadColumnOctaveDrop();
Key.interpolationStride=Heightfield2D::threadColumnInterpolationStrideSubvoxels();
Key.x=X;Key.y=Y;Key.z=Z;
const auto queryContext = ScopedWorldAssemblyFeatureQueriesV1::densityCacheContext(X,Y,Z);
const auto passageContext = FStandaloneShapeWorld::FScopedPassageTileQueries
::densityCacheContext(*ShapeWorld);
const auto mixContext=[](uint64 Value)
{
Value^=Value>>30;Value*=0xbf58476d1ce4e5b9ull;
Value^=Value>>27;Value*=0x94d049bb133111ebull;
return Value^(Value>>31);
};
Key.queryContextLow=mixContext(queryContext[0]^passageContext[0]
^0x9e3779b97f4a7c15ull);
Key.queryContextHigh=mixContext(queryContext[1]^passageContext[1]
^0xd1b54a32d192ed03ull);
const float Value=static_cast<world_assembly_detail::FSharedDensitySampleCache*>(Cache)
->getOrCompute(Key,[&](){return ShapeWorld->DensityAtLattice(X,Y,Z);},OutComputed);
auto& Stats=world_assembly_detail::HeightfieldColumnStats;
if(OutComputed)++Stats.densitySampleCacheComputes;
else ++Stats.densitySampleCacheHits;
return Value;
},static_cast<uint64>(reinterpret_cast<std::uintptr_t>(impl_->worldAssembly.get())),
impl_->lastSequence,key.lod,MeshStep);
}
int64 sampleCount=0;std::vector<float> densityValues;
FVoxelMarchingCubesStageTimings McStageTimings;
TileMesh out;out.key=key;
@@ -2639,12 +2680,19 @@ namespace VoxelForgeCore
VoxelForgeCore::Heightfield2D::threadColumnCacheStats().columnComputeMilliseconds;
const auto MarchingCubesStart=std::chrono::steady_clock::now();
FVoxelUniformBlockProofAuditStats BlockProofAudit;
uint64 SkippedSkirtTriangleSeeds=0;
FVoxelMeshData mesh=mesher.GenerateMesh(origin,MeshStep,MeshCells,nullptr,
MeshBandMinZVoxel,MeshBandMaxZVoxel,&sampleCount,nullptr,nullptr,
(options.hashDensity||options.captureDensitySamples)?&densityValues:nullptr,
options.profileMesherStages?&McStageTimings:nullptr,
options.auditUniformBlockProofs?&BlockProofAudit:nullptr,
options.forceFullDensityCapture);
options.forceFullDensityCapture,&SkippedSkirtTriangleSeeds);
const auto& SampleCacheStats=Heightfield2D::threadColumnCacheStats();
out.diagnostics.densitySampleCacheHits=SampleCacheStats.densitySampleCacheHits;
out.diagnostics.densitySampleCacheComputes=SampleCacheStats.densitySampleCacheComputes;
out.diagnostics.marchingCubesSkirtTrianglesEmitted=
static_cast<uint64>(std::max(0,mesh.NumSkirtTriangles));
out.diagnostics.marchingCubesSkirtTriangleSeedsSkipped=SkippedSkirtTriangleSeeds;
if(options.auditUniformBlockProofs)
{
out.diagnostics.uniformBlockProofsChecked=BlockProofAudit.CheckedBlocks;
@@ -32,6 +32,34 @@ ScopedWorldAssemblyFeatureQueriesV1::ScopedWorldAssemblyFeatureQueriesV1(
for (const auto& query : queries_)
if (forceCandidates_ || query.features.candidateEvaluationUseful)
{ ActiveAssemblyQueries = this; break; }
if (ActiveAssemblyQueries == this)
{
std::uint64_t low = 0x6a09e667f3bcc909ull;
std::uint64_t high = 0xbb67ae8584caa73bull;
const auto add = [&](std::uint64_t value)
{
low ^= value + 0x9e3779b97f4a7c15ull + (low << 6) + (low >> 2);
low *= 0xbf58476d1ce4e5b9ull;
high ^= value + 0x94d049bb133111ebull + (high << 7) + (high >> 3);
high *= 0x9e3779b185ebca87ull;
};
add(forceCandidates_ ? 1u : 0u);
std::uint64_t activeCount = 0;
for (const auto& query : queries_)
if (forceCandidates_ || query.features.candidateEvaluationUseful) ++activeCount;
add(activeCount);
for (const auto& query : queries_)
{
if (!forceCandidates_ && !query.features.candidateEvaluationUseful) continue;
add(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(query.recipe)));
add(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(query.plan)));
add(query.features.densityCacheContextLow);
add(query.features.densityCacheContextHigh);
}
if (low == 0 && high == 0) high = 1;
densityCacheContextLow_ = low;
densityCacheContextHigh_ = high;
}
}
ScopedWorldAssemblyFeatureQueriesV1::~ScopedWorldAssemblyFeatureQueriesV1()
@@ -56,6 +84,15 @@ const WorldAssemblyFeatureTileListV1* ScopedWorldAssemblyFeatureQueriesV1::find(
return nullptr;
}
std::array<std::uint64_t, 2> ScopedWorldAssemblyFeatureQueriesV1::densityCacheContext(
std::int64_t x, std::int64_t y, std::int64_t z) noexcept
{
(void)x; (void)y; (void)z;
if (!ActiveAssemblyQueries) return {};
return {ActiveAssemblyQueries->densityCacheContextLow_,
ActiveAssemblyQueries->densityCacheContextHigh_};
}
std::vector<std::uint32_t> BuildWorldAssemblyFeatureTileListV1(
std::span<const WorldAssemblyFeatureBoundsV1> features,
const std::array<std::int64_t, 3>& tileMinimumSubvoxels,
@@ -124,6 +161,8 @@ namespace world_assembly_detail
{
using FSharedHeightfieldColumnCache =
VoxelForgeCoreShared::TSharedColumnValueCache<HeightfieldPointSample,131072,4>;
using FSharedDensitySampleCache = VoxelForgeCoreShared::TSharedColumnValueCache<
float,32768,4,VoxelForgeCoreShared::FDensitySampleCacheKey>;
// 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.
@@ -2570,6 +2609,7 @@ WorldAssemblyFeatureTileListV1 Heightfield2D::buildFeatureTileList(
bounds.push_back(bound);
}
result.featureIndices=BuildWorldAssemblyFeatureTileListV1(bounds,minimum,maximum);
FinalizeWorldAssemblyFeatureTileListDensityContextV1(result);
return result;
}
@@ -2634,6 +2674,8 @@ void Heightfield2D::resetThreadColumnCacheStats(bool captureCoordinates, bool cl
Stats.columnConflictMisses=0;
Stats.sharedColumnHits=0;
Stats.columnEvaluations=0;
Stats.densitySampleCacheHits=0;
Stats.densitySampleCacheComputes=0;
Stats.columnComputeMilliseconds=0.0;
Stats.captureCoordinates=captureCoordinates;
Stats.coordinateCaptureComplete=true;