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:
1 parent
9898e057fd
commit
4b1108bf86
12 files changed
+751
-92
No files matched your search
@@ -425,6 +425,9 @@ namespace floating_island_detail
|
||||
struct FIslandColumnCacheEntry
|
||||
{
|
||||
bool bValid=false;
|
||||
const FloatingIslandRecipeV1* RecipeIdentity=nullptr;
|
||||
const FloatingIslandPlanV1* PlanIdentity=nullptr;
|
||||
std::uint64_t RecipeContentHash=0,PlanContentHash=0;
|
||||
std::uint32_t Seed=0;
|
||||
std::uint64_t StableId=0;
|
||||
std::int64_t SampleX=0,SampleY=0,CenterX=0,CenterY=0,TopZ=0,Radius=0,TopHalf=0;
|
||||
@@ -432,9 +435,12 @@ namespace floating_island_detail
|
||||
double DeltaX=0.0,DeltaY=0.0,Radial=0.0,Angle=0.0,LobePhase=0.0,TopSurface=0.0;
|
||||
};
|
||||
|
||||
using FSharedIslandColumnCache =
|
||||
VoxelForgeCoreShared::TSharedColumnValueCache<FIslandColumnCacheEntry,16384,4>;
|
||||
|
||||
inline const FIslandColumnCacheEntry& IslandColumnCache(
|
||||
const FloatingIslandRecipeV1& recipe,const FloatingIslandAnchorV1& island,
|
||||
double x,double y)
|
||||
const FloatingIslandRecipeV1& recipe,const FloatingIslandPlanV1& plan,
|
||||
const FloatingIslandAnchorV1& island,double x,double y)
|
||||
{
|
||||
// Density samples arrive on integer Core lattice columns; reuse the exact column metrics
|
||||
// across Z samples without changing the field value or touching shared world state.
|
||||
@@ -450,7 +456,10 @@ namespace floating_island_detail
|
||||
std::uint64_t IndexKey=island.stableId
|
||||
^(static_cast<std::uint64_t>(SampleX)*0x9e3779b97f4a7c15ull)
|
||||
^(static_cast<std::uint64_t>(SampleY)*0xc2b2ae3d27d4eb4full)
|
||||
^(static_cast<std::uint64_t>(recipe.seed)<<23);
|
||||
^(static_cast<std::uint64_t>(recipe.seed)<<23)
|
||||
^recipe.contentHash^std::rotl(plan.contentHash,17)
|
||||
^static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&recipe))
|
||||
^std::rotl(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&plan)),31);
|
||||
IndexKey^=IndexKey>>33;
|
||||
IndexKey*=0xff51afd7ed558ccdull;
|
||||
IndexKey^=IndexKey>>33;
|
||||
@@ -459,7 +468,9 @@ namespace floating_island_detail
|
||||
for(std::size_t Way=0;Way<Ways;++Way)
|
||||
{
|
||||
FIslandColumnCacheEntry& Entry=cache[Base+Way];
|
||||
const bool bKeyMatches=Entry.bValid&&Entry.Seed==recipe.seed
|
||||
const bool bKeyMatches=Entry.bValid&&Entry.RecipeIdentity==&recipe
|
||||
&&Entry.PlanIdentity==&plan&&Entry.RecipeContentHash==recipe.contentHash
|
||||
&&Entry.PlanContentHash==plan.contentHash&&Entry.Seed==recipe.seed
|
||||
&&Entry.StableId==island.stableId
|
||||
&&Entry.SampleX==SampleX&&Entry.SampleY==SampleY
|
||||
&&Entry.CenterX==island.centerSubvoxels[0]
|
||||
@@ -473,32 +484,53 @@ namespace floating_island_detail
|
||||
if(!Entry.bValid)Replacement=&Entry;
|
||||
}
|
||||
|
||||
FIslandColumnCacheEntry& Entry=*Replacement;
|
||||
Entry.bValid=true;
|
||||
Entry.Seed=recipe.seed;
|
||||
Entry.StableId=island.stableId;
|
||||
Entry.SampleX=SampleX;
|
||||
Entry.SampleY=SampleY;
|
||||
Entry.CenterX=island.centerSubvoxels[0];
|
||||
Entry.CenterY=island.centerSubvoxels[1];
|
||||
Entry.TopZ=island.topZSubvoxels;
|
||||
Entry.Radius=island.radiusSubvoxels;
|
||||
Entry.TopHalf=island.topHalfSubvoxels;
|
||||
Entry.TopFlattenQ16=recipe.topFlattenQ16;
|
||||
Entry.ContourWarp=recipe.contourWarpSubvoxels;
|
||||
Entry.DeltaX=x-static_cast<double>(island.centerSubvoxels[0]);
|
||||
Entry.DeltaY=y-static_cast<double>(island.centerSubvoxels[1]);
|
||||
Entry.Radial=std::hypot(Entry.DeltaX,Entry.DeltaY);
|
||||
Entry.Angle=std::atan2(Entry.DeltaY,Entry.DeltaX);
|
||||
Entry.LobePhase=LobePhase(recipe,island);
|
||||
const double EffectiveRadius=std::max(1.0,static_cast<double>(island.radiusSubvoxels)
|
||||
+LobeOffsetWithPhase(recipe,Entry.Angle,static_cast<double>(island.topZSubvoxels),
|
||||
Entry.LobePhase));
|
||||
const double Edge=std::clamp(Entry.Radial/EffectiveRadius,0.0,1.0);
|
||||
const double Drop=(1.0-Q16ToDouble(recipe.topFlattenQ16))
|
||||
*static_cast<double>(island.topHalfSubvoxels)*2.0*Edge*Edge;
|
||||
Entry.TopSurface=static_cast<double>(island.topZSubvoxels)-Drop;
|
||||
return Entry;
|
||||
const auto build=[&]()
|
||||
{
|
||||
FIslandColumnCacheEntry Entry;
|
||||
Entry.bValid=true;
|
||||
Entry.RecipeIdentity=&recipe;
|
||||
Entry.PlanIdentity=&plan;
|
||||
Entry.RecipeContentHash=recipe.contentHash;
|
||||
Entry.PlanContentHash=plan.contentHash;
|
||||
Entry.Seed=recipe.seed;
|
||||
Entry.StableId=island.stableId;
|
||||
Entry.SampleX=SampleX;
|
||||
Entry.SampleY=SampleY;
|
||||
Entry.CenterX=island.centerSubvoxels[0];
|
||||
Entry.CenterY=island.centerSubvoxels[1];
|
||||
Entry.TopZ=island.topZSubvoxels;
|
||||
Entry.Radius=island.radiusSubvoxels;
|
||||
Entry.TopHalf=island.topHalfSubvoxels;
|
||||
Entry.TopFlattenQ16=recipe.topFlattenQ16;
|
||||
Entry.ContourWarp=recipe.contourWarpSubvoxels;
|
||||
Entry.DeltaX=x-static_cast<double>(island.centerSubvoxels[0]);
|
||||
Entry.DeltaY=y-static_cast<double>(island.centerSubvoxels[1]);
|
||||
Entry.Radial=std::hypot(Entry.DeltaX,Entry.DeltaY);
|
||||
Entry.Angle=std::atan2(Entry.DeltaY,Entry.DeltaX);
|
||||
Entry.LobePhase=LobePhase(recipe,island);
|
||||
const double EffectiveRadius=std::max(1.0,static_cast<double>(island.radiusSubvoxels)
|
||||
+LobeOffsetWithPhase(recipe,Entry.Angle,static_cast<double>(island.topZSubvoxels),
|
||||
Entry.LobePhase));
|
||||
const double Edge=std::clamp(Entry.Radial/EffectiveRadius,0.0,1.0);
|
||||
const double Drop=(1.0-Q16ToDouble(recipe.topFlattenQ16))
|
||||
*static_cast<double>(island.topHalfSubvoxels)*2.0*Edge*Edge;
|
||||
Entry.TopSurface=static_cast<double>(island.topZSubvoxels)-Drop;
|
||||
return Entry;
|
||||
};
|
||||
FIslandColumnCacheEntry Entry{};
|
||||
if(auto* shared=FSharedIslandColumnCache::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,SampleX,SampleY,island.stableId};
|
||||
bool computed=false;
|
||||
Entry=shared->getOrCompute(key,build,computed);
|
||||
}
|
||||
else Entry=build();
|
||||
*Replacement=Entry;
|
||||
return *Replacement;
|
||||
}
|
||||
|
||||
inline std::int64_t ScaledQ16(std::int64_t value, std::int64_t scaleQ16)
|
||||
@@ -641,6 +673,7 @@ namespace floating_island_detail
|
||||
}
|
||||
|
||||
inline double IslandDensity(const FloatingIslandRecipeV1& recipe,
|
||||
const FloatingIslandPlanV1& plan,
|
||||
const FloatingIslandAnchorV1& island,
|
||||
double x, double y, double z)
|
||||
{
|
||||
@@ -665,7 +698,7 @@ namespace floating_island_detail
|
||||
std::max({z - top, radial - envelope, bottomZ - z}), x, y, z);
|
||||
}
|
||||
|
||||
const FIslandColumnCacheEntry& Column=IslandColumnCache(recipe,island,x,y);
|
||||
const FIslandColumnCacheEntry& Column=IslandColumnCache(recipe,plan,island,x,y);
|
||||
const double dx=Column.DeltaX;
|
||||
const double dy=Column.DeltaY;
|
||||
const double radial=Column.Radial;
|
||||
@@ -733,7 +766,7 @@ namespace floating_island_detail
|
||||
double result = static_cast<double>(MaxDensity);
|
||||
for (const auto& island : plan.islands)
|
||||
{
|
||||
double group = IslandDensity(recipe, island,
|
||||
double group = IslandDensity(recipe, plan, island,
|
||||
static_cast<double>(x), static_cast<double>(y), static_cast<double>(z));
|
||||
for (const auto& edge : plan.clusterEdges)
|
||||
{
|
||||
@@ -769,7 +802,7 @@ namespace floating_island_detail
|
||||
const auto evaluateLocalGroup = [&](std::size_t islandIndex)
|
||||
{
|
||||
const auto& island = plan.islands[islandIndex];
|
||||
double group = IslandDensity(recipe, island,
|
||||
double group = IslandDensity(recipe, plan, island,
|
||||
static_cast<double>(x), static_cast<double>(y), static_cast<double>(z));
|
||||
for (const std::uint32_t edgeIndex : featureIndices)
|
||||
{
|
||||
@@ -795,7 +828,7 @@ namespace floating_island_detail
|
||||
const auto evaluateDistantGroup = [&](std::size_t islandIndex)
|
||||
{
|
||||
const auto& island = plan.islands[islandIndex];
|
||||
double group = IslandDensity(recipe, island,
|
||||
double group = IslandDensity(recipe, plan, island,
|
||||
static_cast<double>(x), static_cast<double>(y), static_cast<double>(z));
|
||||
for (const auto& edge : plan.clusterEdges)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user