/
redgpu
/
tech5
Обзор
Документация
Войти
/
redgpu
/
tech5
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
source/shared/idlib/metrics/plog.cpp
200 строк
6 KB
Justin Marshall
First pass idLib conversion from hex rays4.
08 авг 2026, 23:54
08 авг 2026, 23:54
09a4cb9
Код
Авторство
О чём код?
#include "plog.h" #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #ifndef NOMINMAX #define NOMINMAX #endif #include <windows.h> #include <algorithm> #include <cstdio> #include <cstring> namespace { std::int64_t ClockTicks() { LARGE_INTEGER counter = {}; QueryPerformanceCounter(&counter); return counter.QuadPart; } double TicksPerMillisecond() { static double value = 0.0; if (value == 0.0) { LARGE_INTEGER frequency = {}; QueryPerformanceFrequency(&frequency); value = static_cast<double>(frequency.QuadPart) / 1000.0; } return value; } float TicksToMilliseconds(const std::int64_t ticks) { return static_cast<float>(static_cast<double>(ticks) / TicksPerMillisecond()); } } // namespace idPLog pLog; idPLog::idPLog() : treeEntries(64), logEntries(64), lastEntry(0), overHeadTicks(-1), groupMask(0) { Clear(); } void idPLog::Clear() { treeEntries.Clear(); logEntries.Clear(); logEntry_t* const root = logEntries.Alloc(); if (root != nullptr) { root->label = "root"; root->parent = 0; root->totalTicks = 0; } lastEntry = 0; } void idPLog::EnsureEntries() { logEntries.Reserve(4096); treeEntries.Reserve(4096); } std::int64_t idPLog::GetOverHeadTicks() { if (overHeadTicks >= 0) return overHeadTicks; std::int64_t best = INT64_MAX; for (int pass = 0; pass < 4; ++pass) { const std::int64_t start = ClockTicks(); for (int index = 0; index < 1000; ++index) { const std::int64_t end = ClockTicks(); (void)end; } best = std::min(best, ClockTicks() - start); } overHeadTicks = static_cast<int>(best / 1000); return overHeadTicks; } void idPLog::SubtractOverhead() { const std::int64_t overhead = GetOverHeadTicks(); for (int index = 1; index < logEntries.Num(); ++index) { const int parent = logEntries[index].parent; if (parent >= 0 && parent < logEntries.Num()) { logEntries[parent].totalTicks = std::max<std::int64_t>(0, logEntries[parent].totalTicks - overhead); } } } float idPLog::BuildLogData(const float thresholdMS, const std::int64_t adjustByTicks) { treeEntries.Clear(); treeEntry_t* const root = treeEntries.Alloc(); if (root == nullptr) return 0.0f; root->label = "root"; root->depth = 0; root->numHits = 1; root->parent = -1; root->firstChild = -1; root->nextChild = -1; for (int index = 1; index < logEntries.Num(); ++index) { const logEntry_t& source = logEntries[index]; int treeParent = 0; if (source.parent > 0 && source.parent < index) { const char* const parentLabel = logEntries[source.parent].label; for (int candidate = treeEntries.Num() - 1; candidate > 0; --candidate) { if (treeEntries[candidate].label == parentLabel || std::strcmp(treeEntries[candidate].label, parentLabel) == 0) { treeParent = candidate; break; } } } int destination = -1; for (int candidate = 1; candidate < treeEntries.Num(); ++candidate) { if (treeEntries[candidate].parent == treeParent && (treeEntries[candidate].label == source.label || std::strcmp(treeEntries[candidate].label, source.label) == 0)) { destination = candidate; break; } } if (destination < 0) { treeEntry_t* const entry = treeEntries.Alloc(); if (entry == nullptr) break; destination = treeEntries.Num() - 1; entry->label = source.label; entry->depth = treeEntries[treeParent].depth + 1; entry->parent = treeParent; entry->firstChild = -1; entry->nextChild = treeEntries[treeParent].firstChild; treeEntries[treeParent].firstChild = destination; } treeEntry_t& entry = treeEntries[destination]; const std::int64_t adjusted = std::max<std::int64_t>(0, source.totalTicks - adjustByTicks); entry.totalTicks += adjusted; ++entry.numHits; root->totalTicks += adjusted; } if (thresholdMS > 0.0f) { // Keep the recovered table intact; the threshold only controls output. } return TicksToMilliseconds(root->totalTicks); } void idPLog::ShowUniqueEntries(const float thresholdMS, const std::int64_t adjustByTicks) { BuildLogData(thresholdMS, adjustByTicks); for (int index = 1; index < treeEntries.Num(); ++index) { const treeEntry_t& entry = treeEntries[index]; const float milliseconds = TicksToMilliseconds(entry.totalTicks); if (milliseconds >= thresholdMS) { std::printf("%-40s %6d %10.3f ms\n", entry.label, entry.numHits, milliseconds); } } } void idPLog::ShowCallGraph(const float thresholdMS, const std::int64_t adjustByTicks) { BuildLogData(thresholdMS, adjustByTicks); for (int index = 1; index < treeEntries.Num(); ++index) { const treeEntry_t& entry = treeEntries[index]; const float milliseconds = TicksToMilliseconds(entry.totalTicks); if (milliseconds >= thresholdMS) { std::printf("%*s%s: %.3f ms (%d)\n", entry.depth * 2, "", entry.label, milliseconds, entry.numHits); } } } idPLogScope::idPLogScope(idPLog& log, const std::uint64_t mask, const char* label) : logIndex(-1), pLog(&log) { if (!log.IsGroupEnabled(mask)) return; idPLog::logEntry_t* const entry = log.logEntries.Alloc(); if (entry == nullptr) return; entry->label = label == nullptr ? "<unnamed>" : label; entry->parent = log.lastEntry; entry->totalTicks = ClockTicks(); logIndex = log.logEntries.Num() - 1; log.lastEntry = logIndex; } idPLogScope::~idPLogScope() { End(); } void idPLogScope::End(std::int64_t* totalTicks) { if (logIndex < 0 || pLog == nullptr) return; idPLog::logEntry_t& entry = pLog->logEntries[logIndex]; entry.totalTicks = ClockTicks() - entry.totalTicks; if (totalTicks != nullptr) *totalTicks = entry.totalTicks; pLog->lastEntry = entry.parent; logIndex = -1; }