diff options
Diffstat (limited to 'src/zen/trace/trace_cache.cpp')
| -rw-r--r-- | src/zen/trace/trace_cache.cpp | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/zen/trace/trace_cache.cpp b/src/zen/trace/trace_cache.cpp index 165c1eecf..954df14e0 100644 --- a/src/zen/trace/trace_cache.cpp +++ b/src/zen/trace/trace_cache.cpp @@ -448,6 +448,53 @@ namespace { return ToSharedBuffer(W); } + // -- Counters section -- + + SharedBuffer WriteCountersSection(const TraceModel& Model, StringTableBuilder& Strings) + { + BinaryWriter W; + + uint32_t DefCount = uint32_t(Model.CounterDefs.size()); + WritePod(W, DefCount); + for (const TraceModel::CounterDef& D : Model.CounterDefs) + { + CounterDefPod P = {}; + P.Id = D.Id; + P.Type = D.Type; + P.DisplayHint = D.DisplayHint; + P.Name = Strings.Intern(D.Name); + WritePod(W, P); + } + + uint32_t SeriesCount = uint32_t(Model.CounterTimeSeries.size()); + WritePod(W, SeriesCount); + // First pass: headers (so the reader can size each series before it + // reads samples). + for (const TraceModel::CounterSeries& S : Model.CounterTimeSeries) + { + CounterHeaderPod H = {}; + H.Id = S.Id; + H.Type = S.Type; + H.SampleCount = uint32_t(S.Samples.size()); + H.Min = S.Min; + H.Max = S.Max; + WritePod(W, H); + } + // Second pass: contiguous sample blob in the same order as headers. + for (const TraceModel::CounterSeries& S : Model.CounterTimeSeries) + { + for (const TraceModel::CounterSample& Sample : S.Samples) + { + CounterSamplePod SP = {}; + SP.TimeUs = Sample.TimeUs; + SP.Value = Sample.Value; + WritePod(W, SP); + } + } + + return ToSharedBuffer(W); + } + // -- Symbols section -- SharedBuffer WriteSymbolsSection(const eastl::hash_map<uint64_t, std::string>& ResolvedSymbols, StringTableBuilder& Strings) @@ -860,6 +907,67 @@ namespace { return true; } + bool ReadCountersSection(const SharedBuffer& Data, const StringTableReader& Strings, TraceModel& Model) + { + BinaryReader R(Data.GetData(), Data.GetSize()); + + uint32_t DefCount = 0; + if (!ReadUint32(R, DefCount)) + { + return false; + } + Model.CounterDefs.resize(DefCount); + for (uint32_t I = 0; I < DefCount; ++I) + { + CounterDefPod P; + if (!ReadPod(R, P)) + { + return false; + } + Model.CounterDefs[I].Id = P.Id; + Model.CounterDefs[I].Type = P.Type; + Model.CounterDefs[I].DisplayHint = P.DisplayHint; + Model.CounterDefs[I].Name = std::string(Strings.Get(P.Name)); + } + + uint32_t SeriesCount = 0; + if (!ReadUint32(R, SeriesCount)) + { + return false; + } + eastl::vector<CounterHeaderPod> Headers(SeriesCount); + for (uint32_t I = 0; I < SeriesCount; ++I) + { + if (!ReadPod(R, Headers[I])) + { + return false; + } + } + Model.CounterTimeSeries.resize(SeriesCount); + for (uint32_t I = 0; I < SeriesCount; ++I) + { + const CounterHeaderPod& H = Headers[I]; + TraceModel::CounterSeries& Out = Model.CounterTimeSeries[I]; + Out.Id = H.Id; + Out.Type = H.Type; + Out.Count = H.SampleCount; + Out.Min = H.Min; + Out.Max = H.Max; + Out.Samples.resize(H.SampleCount); + for (uint32_t J = 0; J < H.SampleCount; ++J) + { + CounterSamplePod SP; + if (!ReadPod(R, SP)) + { + return false; + } + Out.Samples[J].TimeUs = SP.TimeUs; + Out.Samples[J].Value = SP.Value; + } + } + return true; + } + // =========================================================================== // File-level helpers // =========================================================================== @@ -913,6 +1021,7 @@ WriteAnalyzeCache(const std::filesystem::path& CachePath, SharedBuffer MemoryRaw = WriteMemorySection(Model, Strings); SharedBuffer CallstacksRaw = WriteCallstacksSection(Model); SharedBuffer SymbolsRaw = WriteSymbolsSection(ResolvedSymbols, Strings); + SharedBuffer CountersRaw = WriteCountersSection(Model, Strings); SharedBuffer StringTableRaw = Strings.Serialize(); // Compress each section @@ -922,6 +1031,7 @@ WriteAnalyzeCache(const std::filesystem::path& CachePath, Sections[uint32_t(CacheSectionId::Memory)] = CompressSection(MemoryRaw); Sections[uint32_t(CacheSectionId::Callstacks)] = CompressSection(CallstacksRaw); Sections[uint32_t(CacheSectionId::Symbols)] = CompressSection(SymbolsRaw); + Sections[uint32_t(CacheSectionId::Counters)] = CompressSection(CountersRaw); // Build file header CacheFileHeader Header = {}; @@ -1091,6 +1201,16 @@ TryLoadAnalyzeCache(const std::filesystem::path& CachePath, const std::filesyste } } + SharedBuffer CountersData = DecompressSection(Base, Directory[uint32_t(CacheSectionId::Counters)]); + if (!CountersData.IsNull()) + { + if (!ReadCountersSection(CountersData, Strings, Result.Model)) + { + ZEN_DEBUG("Analysis cache: failed to read counters section"); + // Counters are optional -- continue without them. + } + } + ZEN_INFO("Loaded analysis from cache ({})", zen::NiceBytes(FileData.Size())); return Result; } |