Skip to content

Commit 15b80eb

Browse files
committed
Split include session cache reads and writes
1 parent 4aa78fd commit 15b80eb

6 files changed

Lines changed: 143 additions & 25 deletions

File tree

include/nbl/asset/utils/IShaderCompiler.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
9898
public:
9999
struct SSessionCache
100100
{
101+
struct Stats
102+
{
103+
uint64_t lookupFound = 0ull;
104+
uint64_t lookupMissing = 0ull;
105+
uint64_t lookupMiss = 0ull;
106+
uint64_t storeFound = 0ull;
107+
uint64_t storeMissing = 0ull;
108+
};
109+
101110
enum class LookupResult : uint8_t
102111
{
103112
Miss,
@@ -110,10 +119,12 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
110119
void clear();
111120
LookupResult lookup(const std::string& key, IIncludeLoader::found_t& result) const;
112121
void store(const std::string& key, IIncludeLoader::found_t result);
122+
Stats snapshotStats() const;
113123

114124
bool threadSafe = false;
115125

116126
mutable std::mutex mutex;
127+
mutable Stats stats;
117128
core::unordered_map<std::string, IIncludeLoader::found_t> found;
118129
core::unordered_set<std::string> missing;
119130
};
@@ -123,12 +134,12 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
123134
// ! includes within <>
124135
// @param requestingSourceDir: the directory where the incude was requested
125136
// @param includeName: the string within <> of the include preprocessing directive
126-
IIncludeLoader::found_t getIncludeStandard(const system::path& requestingSourceDir, const std::string& includeName, bool needHash = true, SSessionCache* sessionCache = nullptr) const;
137+
IIncludeLoader::found_t getIncludeStandard(const system::path& requestingSourceDir, const std::string& includeName, bool needHash = true, SSessionCache* readSessionCache = nullptr, SSessionCache* writeSessionCache = nullptr) const;
127138

128139
// ! includes within ""
129140
// @param requestingSourceDir: the directory where the incude was requested
130141
// @param includeName: the string within "" of the include preprocessing directive
131-
IIncludeLoader::found_t getIncludeRelative(const system::path& requestingSourceDir, const std::string& includeName, bool needHash = true, SSessionCache* sessionCache = nullptr) const;
142+
IIncludeLoader::found_t getIncludeRelative(const system::path& requestingSourceDir, const std::string& includeName, bool needHash = true, SSessionCache* readSessionCache = nullptr, SSessionCache* writeSessionCache = nullptr) const;
132143

133144
inline core::smart_refctd_ptr<CFileSystemIncludeLoader> getDefaultFileSystemLoader() const { return m_defaultFileSystemLoader; }
134145

@@ -196,7 +207,8 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
196207
std::string_view sourceIdentifier = "";
197208
system::logger_opt_ptr logger = nullptr;
198209
const CIncludeFinder* includeFinder = nullptr;
199-
mutable CIncludeFinder::SSessionCache* includeSessionCache = nullptr;
210+
CIncludeFinder::SSessionCache* readIncludeSessionCache = nullptr;
211+
CIncludeFinder::SSessionCache* writeIncludeSessionCache = nullptr;
200212
std::span<const SMacroDefinition> extraDefines = {};
201213
E_SPIRV_VERSION targetSpirvVersion = E_SPIRV_VERSION::ESV_1_6;
202214
bool depfile = false;

src/nbl/asset/utils/CGLSLCompiler.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,13 @@ namespace nbl::asset::impl
4444
class Includer : public shaderc::CompileOptions::IncluderInterface
4545
{
4646
const IShaderCompiler::CIncludeFinder* m_defaultIncludeFinder;
47-
IShaderCompiler::CIncludeFinder::SSessionCache* m_includeSessionCache;
47+
IShaderCompiler::CIncludeFinder::SSessionCache* m_readIncludeSessionCache;
48+
IShaderCompiler::CIncludeFinder::SSessionCache* m_writeIncludeSessionCache;
4849
const system::ISystem* m_system;
4950
const uint32_t m_maxInclCnt;
5051

5152
public:
52-
Includer(const IShaderCompiler::CIncludeFinder* _inclFinder, IShaderCompiler::CIncludeFinder::SSessionCache* _includeSessionCache, const system::ISystem* _fs, uint32_t _maxInclCnt) : m_defaultIncludeFinder(_inclFinder), m_includeSessionCache(_includeSessionCache), m_system(_fs), m_maxInclCnt{ _maxInclCnt } {}
53+
Includer(const IShaderCompiler::CIncludeFinder* _inclFinder, IShaderCompiler::CIncludeFinder::SSessionCache* _readIncludeSessionCache, IShaderCompiler::CIncludeFinder::SSessionCache* _writeIncludeSessionCache, const system::ISystem* _fs, uint32_t _maxInclCnt) : m_defaultIncludeFinder(_inclFinder), m_readIncludeSessionCache(_readIncludeSessionCache), m_writeIncludeSessionCache(_writeIncludeSessionCache), m_system(_fs), m_maxInclCnt{ _maxInclCnt } {}
5354

5455
//_requesting_source in top level #include's is what shaderc::Compiler's compiling functions get as `input_file_name` parameter
5556
//so in order for properly working relative #include's (""-type) `input_file_name` has to be path to file from which the GLSL source really come from
@@ -82,11 +83,11 @@ namespace nbl::asset::impl
8283
IShaderCompiler::IIncludeLoader::found_t result;
8384
if (_type == shaderc_include_type_relative)
8485
{
85-
result = m_defaultIncludeFinder->getIncludeRelative(relDir, _requested_source, true, m_includeSessionCache);
86+
result = m_defaultIncludeFinder->getIncludeRelative(relDir, _requested_source, true, m_readIncludeSessionCache, m_writeIncludeSessionCache);
8687
}
8788
else //shaderc_include_type_standard
8889
{
89-
result = m_defaultIncludeFinder->getIncludeStandard(relDir, _requested_source, true, m_includeSessionCache);
90+
result = m_defaultIncludeFinder->getIncludeStandard(relDir, _requested_source, true, m_readIncludeSessionCache, m_writeIncludeSessionCache);
9091
}
9192

9293
if (!result)
@@ -139,8 +140,16 @@ std::string CGLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
139140
{
140141
auto effectiveOptions = preprocessOptions;
141142
IShaderCompiler::CIncludeFinder::SSessionCache localIncludeSessionCache;
142-
if (effectiveOptions.includeFinder && !effectiveOptions.includeSessionCache)
143-
effectiveOptions.includeSessionCache = &localIncludeSessionCache;
143+
if (effectiveOptions.includeFinder)
144+
{
145+
if (!effectiveOptions.readIncludeSessionCache && !effectiveOptions.writeIncludeSessionCache)
146+
{
147+
effectiveOptions.readIncludeSessionCache = &localIncludeSessionCache;
148+
effectiveOptions.writeIncludeSessionCache = &localIncludeSessionCache;
149+
}
150+
else if (!effectiveOptions.readIncludeSessionCache && effectiveOptions.writeIncludeSessionCache)
151+
effectiveOptions.readIncludeSessionCache = effectiveOptions.writeIncludeSessionCache;
152+
}
144153

145154
if (!preprocessOptions.extraDefines.empty())
146155
{
@@ -157,7 +166,7 @@ std::string CGLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
157166

158167
if (effectiveOptions.includeFinder != nullptr)
159168
{
160-
options.SetIncluder(std::make_unique<impl::Includer>(effectiveOptions.includeFinder, effectiveOptions.includeSessionCache, m_system.get(), /*maxSelfInclusionCount*/5));//custom #include handler
169+
options.SetIncluder(std::make_unique<impl::Includer>(effectiveOptions.includeFinder, effectiveOptions.readIncludeSessionCache, effectiveOptions.writeIncludeSessionCache, m_system.get(), /*maxSelfInclusionCount*/5));//custom #include handler
161170
}
162171
const shaderc_shader_kind scstage = stage == IShader::E_SHADER_STAGE::ESS_UNKNOWN ? shaderc_glsl_infer_from_source : ESStoShadercEnum(stage);
163172
auto res = comp.PreprocessGlsl(code, scstage, effectiveOptions.sourceIdentifier.data(), options);

src/nbl/asset/utils/CHLSLCompiler.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,8 +456,16 @@ static std::string preprocessShaderImpl(
456456
{
457457
auto effectiveOptions = preprocessOptions;
458458
IShaderCompiler::CIncludeFinder::SSessionCache localIncludeSessionCache;
459-
if (effectiveOptions.includeFinder && !effectiveOptions.includeSessionCache)
460-
effectiveOptions.includeSessionCache = &localIncludeSessionCache;
459+
if (effectiveOptions.includeFinder)
460+
{
461+
if (!effectiveOptions.readIncludeSessionCache && !effectiveOptions.writeIncludeSessionCache)
462+
{
463+
effectiveOptions.readIncludeSessionCache = &localIncludeSessionCache;
464+
effectiveOptions.writeIncludeSessionCache = &localIncludeSessionCache;
465+
}
466+
else if (!effectiveOptions.readIncludeSessionCache && effectiveOptions.writeIncludeSessionCache)
467+
effectiveOptions.readIncludeSessionCache = effectiveOptions.writeIncludeSessionCache;
468+
}
461469

462470
const bool depfileEnabled = effectiveOptions.depfile;
463471
if (depfileEnabled)

src/nbl/asset/utils/CWaveStringResolver.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,19 @@ constexpr size_t kWaveFailureLogOutputTailMaxChars = 4096ull;
2525
constexpr size_t kWaveFailureLogOutputTailMaxLines = 16ull;
2626
constexpr size_t kWaveFailureLogTokenPreviewMaxChars = 160ull;
2727

28+
auto subtractSessionCacheStats(
29+
const IShaderCompiler::CIncludeFinder::SSessionCache::Stats& end,
30+
const IShaderCompiler::CIncludeFinder::SSessionCache::Stats& begin) -> IShaderCompiler::CIncludeFinder::SSessionCache::Stats
31+
{
32+
IShaderCompiler::CIncludeFinder::SSessionCache::Stats result;
33+
result.lookupFound = end.lookupFound - begin.lookupFound;
34+
result.lookupMissing = end.lookupMissing - begin.lookupMissing;
35+
result.lookupMiss = end.lookupMiss - begin.lookupMiss;
36+
result.storeFound = end.storeFound - begin.storeFound;
37+
result.storeMissing = end.storeMissing - begin.storeMissing;
38+
return result;
39+
}
40+
2841
struct WaveRenderProgress
2942
{
3043
core::string output;
@@ -305,6 +318,10 @@ std::string preprocessImpl(
305318
const bool withCaching,
306319
std::function<void(nbl::wave::context&)> post)
307320
{
321+
const auto emptySessionCacheStats = IShaderCompiler::CIncludeFinder::SSessionCache::Stats{};
322+
const auto readSessionCacheStatsBegin = preprocessOptions.readIncludeSessionCache ? preprocessOptions.readIncludeSessionCache->snapshotStats() : emptySessionCacheStats;
323+
const auto writeSessionCacheStatsBegin = preprocessOptions.writeIncludeSessionCache ? preprocessOptions.writeIncludeSessionCache->snapshotStats() : emptySessionCacheStats;
324+
308325
nbl::wave::context context(code.begin(), code.end(), preprocessOptions.sourceIdentifier.data(), { preprocessOptions });
309326

310327
WaveRenderProgress renderProgress;
@@ -383,6 +400,11 @@ std::string preprocessImpl(
383400
}
384401

385402
post(context);
403+
const auto readSessionCacheStatsEnd = preprocessOptions.readIncludeSessionCache ? preprocessOptions.readIncludeSessionCache->snapshotStats() : emptySessionCacheStats;
404+
const auto writeSessionCacheStatsEnd = preprocessOptions.writeIncludeSessionCache ? preprocessOptions.writeIncludeSessionCache->snapshotStats() : emptySessionCacheStats;
405+
nbl::wave::detail::set_session_cache_perf_stats(
406+
subtractSessionCacheStats(readSessionCacheStatsEnd, readSessionCacheStatsBegin),
407+
subtractSessionCacheStats(writeSessionCacheStatsEnd, writeSessionCacheStatsBegin));
386408
nbl::wave::detail::dump_perf_stats();
387409

388410
return std::move(renderProgress.output);

src/nbl/asset/utils/IShaderCompiler.cpp

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,33 @@ std::string makeIncludeSessionCacheKey(const system::path& requestingSourceDir,
694694
return key;
695695
}
696696

697+
auto lookupIncludeSessionCache(IShaderCompiler::CIncludeFinder::SSessionCache* readCache, IShaderCompiler::CIncludeFinder::SSessionCache* writeCache, const std::string& key, IShaderCompiler::IIncludeLoader::found_t& result) -> IShaderCompiler::CIncludeFinder::SSessionCache::LookupResult
698+
{
699+
using LookupResult = IShaderCompiler::CIncludeFinder::SSessionCache::LookupResult;
700+
const auto lookupResult = readCache ? readCache->lookup(key, result) : LookupResult::Miss;
701+
if (readCache && writeCache && readCache != writeCache)
702+
{
703+
switch (lookupResult)
704+
{
705+
case LookupResult::Found:
706+
writeCache->store(key, result);
707+
break;
708+
case LookupResult::Missing:
709+
writeCache->store(key, {});
710+
break;
711+
case LookupResult::Miss:
712+
break;
713+
}
714+
}
715+
return lookupResult;
716+
}
717+
718+
void writeIncludeSessionCache(IShaderCompiler::CIncludeFinder::SSessionCache* writeCache, const std::string& key, const IShaderCompiler::IIncludeLoader::found_t& result)
719+
{
720+
if (writeCache)
721+
writeCache->store(key, result);
722+
}
723+
697724
}
698725

699726
void IShaderCompiler::CIncludeFinder::SSessionCache::clear()
@@ -711,11 +738,16 @@ auto IShaderCompiler::CIncludeFinder::SSessionCache::lookup(const std::string& k
711738
{
712739
if (const auto foundIt = found.find(key); foundIt != found.end())
713740
{
741+
++stats.lookupFound;
714742
result = foundIt->second;
715743
return LookupResult::Found;
716744
}
717745
if (missing.contains(key))
746+
{
747+
++stats.lookupMissing;
718748
return LookupResult::Missing;
749+
}
750+
++stats.lookupMiss;
719751
return LookupResult::Miss;
720752
});
721753
}
@@ -726,9 +758,23 @@ void IShaderCompiler::CIncludeFinder::SSessionCache::store(const std::string& ke
726758
{
727759
missing.erase(key);
728760
if (result)
761+
{
762+
++stats.storeFound;
729763
found.insert_or_assign(key, std::move(result));
764+
}
730765
else
766+
{
767+
++stats.storeMissing;
731768
missing.insert(key);
769+
}
770+
});
771+
}
772+
773+
auto IShaderCompiler::CIncludeFinder::SSessionCache::snapshotStats() const -> Stats
774+
{
775+
return withSessionCacheLock(const_cast<SSessionCache*>(this), [&]() -> Stats
776+
{
777+
return stats;
732778
});
733779
}
734780

@@ -744,12 +790,12 @@ IShaderCompiler::CIncludeFinder::CIncludeFinder(core::smart_refctd_ptr<system::I
744790
// @param requestingSourceDir: the directory where the incude was requested
745791
// @param includeName: the string within <> of the include preprocessing directive
746792
// @param
747-
auto IShaderCompiler::CIncludeFinder::getIncludeStandard(const system::path& requestingSourceDir, const std::string& includeName, bool needHash, SSessionCache* sessionCache) const -> IIncludeLoader::found_t
793+
auto IShaderCompiler::CIncludeFinder::getIncludeStandard(const system::path& requestingSourceDir, const std::string& includeName, bool needHash, SSessionCache* readSessionCache, SSessionCache* writeSessionCache) const -> IIncludeLoader::found_t
748794
{
749795
const auto lookupName = normalizeIncludeLookupName(includeName);
750796
const auto cacheKey = makeIncludeSessionCacheKey(requestingSourceDir, lookupName, needHash, 'S');
751797
IShaderCompiler::IIncludeLoader::found_t retVal;
752-
switch (sessionCache ? sessionCache->lookup(cacheKey, retVal) : SSessionCache::LookupResult::Miss)
798+
switch (lookupIncludeSessionCache(readSessionCache, writeSessionCache, cacheKey, retVal))
753799
{
754800
case SSessionCache::LookupResult::Found:
755801
return retVal;
@@ -774,20 +820,19 @@ auto IShaderCompiler::CIncludeFinder::getIncludeStandard(const system::path& req
774820
hasher.update(reinterpret_cast<uint8_t*>(retVal.contents.data()), retVal.contents.size() * (sizeof(char) / sizeof(uint8_t)));
775821
retVal.hash = static_cast<core::blake3_hash_t>(hasher);
776822
}
777-
if (sessionCache)
778-
sessionCache->store(cacheKey, retVal);
823+
writeIncludeSessionCache(writeSessionCache, cacheKey, retVal);
779824
return retVal;
780825
}
781826

782827
// ! includes within ""
783828
// @param requestingSourceDir: the directory where the incude was requested
784829
// @param includeName: the string within "" of the include preprocessing directive
785-
auto IShaderCompiler::CIncludeFinder::getIncludeRelative(const system::path& requestingSourceDir, const std::string& includeName, bool needHash, SSessionCache* sessionCache) const -> IIncludeLoader::found_t
830+
auto IShaderCompiler::CIncludeFinder::getIncludeRelative(const system::path& requestingSourceDir, const std::string& includeName, bool needHash, SSessionCache* readSessionCache, SSessionCache* writeSessionCache) const -> IIncludeLoader::found_t
786831
{
787832
const auto lookupName = normalizeIncludeLookupName(includeName);
788833
const auto cacheKey = makeIncludeSessionCacheKey(requestingSourceDir, lookupName, needHash, 'R');
789834
IShaderCompiler::IIncludeLoader::found_t retVal;
790-
switch (sessionCache ? sessionCache->lookup(cacheKey, retVal) : SSessionCache::LookupResult::Miss)
835+
switch (lookupIncludeSessionCache(readSessionCache, writeSessionCache, cacheKey, retVal))
791836
{
792837
case SSessionCache::LookupResult::Found:
793838
return retVal;
@@ -809,8 +854,7 @@ auto IShaderCompiler::CIncludeFinder::getIncludeRelative(const system::path& req
809854
hasher.update(reinterpret_cast<uint8_t*>(retVal.contents.data()), retVal.contents.size() * (sizeof(char) / sizeof(uint8_t)));
810855
retVal.hash = static_cast<core::blake3_hash_t>(hasher);
811856
}
812-
if (sessionCache)
813-
sessionCache->store(cacheKey, retVal);
857+
writeIncludeSessionCache(writeSessionCache, cacheKey, retVal);
814858
return retVal;
815859
}
816860

0 commit comments

Comments
 (0)