yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Ellie HermaszewskaPerf improvements to IR serialization (#7751)28758e0e4

master
3.5 KiB127 linesraw
1#include "slang-performance-profiler.h"
2
3#include "slang-dictionary.h"
4
5namespace Slang
6{
7class PerformanceProfilerImpl : public PerformanceProfiler
8{
9public:
10    OrderedDictionary<const char*, FuncProfileInfo> data;
11
12    virtual FuncProfileContext enterFunction(const char* funcName) override
13    {
14        auto entry = data.tryGetValue(funcName);
15        if (!entry)
16        {
17            data.add(funcName, FuncProfileInfo());
18            entry = data.tryGetValue(funcName);
19        }
20        entry->invocationCount++;
21        FuncProfileContext ctx;
22        ctx.funcName = funcName;
23        ctx.startTime = std::chrono::high_resolution_clock::now();
24        return ctx;
25    }
26    virtual void exitFunction(FuncProfileContext ctx) override
27    {
28        auto endTime = std::chrono::high_resolution_clock::now();
29        auto duration = endTime - ctx.startTime;
30        auto entry = data.tryGetValue(ctx.funcName);
31        entry->duration += duration;
32    }
33    virtual void getResult(StringBuilder& out) override
34    {
35        char buffer[512];
36        for (const auto& func : data)
37        {
38            auto microseconds =
39                std::chrono::duration_cast<std::chrono::microseconds>(func.value.duration);
40            double milliseconds = microseconds.count() / 1000.0;
41            snprintf(
42                buffer,
43                sizeof(buffer),
44                "[*] %30s \t%d \t%8.2fms\n",
45                func.key,
46                func.value.invocationCount,
47                milliseconds);
48
49            out << buffer;
50        }
51    }
52
53
54    virtual void clear() override { data.clear(); }
55    virtual void dispose() override { data = decltype(data)(); }
56};
57
58PerformanceProfiler* Slang::PerformanceProfiler::getProfiler()
59{
60    thread_local static PerformanceProfilerImpl profiler = PerformanceProfilerImpl();
61    return &profiler;
62}
63
64SlangProfiler::SlangProfiler(PerformanceProfiler* profiler)
65{
66    PerformanceProfilerImpl* profilerImpl = static_cast<PerformanceProfilerImpl*>(profiler);
67    size_t entryCount = profilerImpl->data.getCount();
68
69    m_profilEntries.reserve(entryCount);
70
71    int index = 0;
72    for (auto func : profilerImpl->data)
73    {
74        ProfileInfo profileEntry{};
75        size_t strSize = std::min(sizeof(profileEntry.funcName) - 1, strlen(func.key));
76
77        if (strSize > 0)
78        {
79            memcpy(profileEntry.funcName, func.key, strSize);
80        }
81        profileEntry.invocationCount = func.value.invocationCount;
82        profileEntry.duration = func.value.duration;
83
84        m_profilEntries.insert(index, profileEntry);
85        index++;
86    }
87}
88
89ISlangUnknown* SlangProfiler::getInterface(const Guid& guid)
90{
91    if (guid == SlangProfiler::getTypeGuid())
92        return static_cast<ISlangUnknown*>(this);
93    else
94        return nullptr;
95}
96
97size_t SlangProfiler::getEntryCount()
98{
99    return m_profilEntries.getCount();
100}
101
102const char* SlangProfiler::getEntryName(uint32_t index)
103{
104    if (index >= (uint32_t)m_profilEntries.getCount())
105        return nullptr;
106
107    return m_profilEntries[index].funcName;
108}
109
110long SlangProfiler::getEntryTimeMS(uint32_t index)
111{
112    if (index >= (uint32_t)m_profilEntries.getCount())
113        return 0;
114
115    auto milliseconds =
116        std::chrono::duration_cast<std::chrono::milliseconds>(m_profilEntries[index].duration);
117    return (long)milliseconds.count();
118}
119
120uint32_t SlangProfiler::getEntryInvocationTimes(uint32_t index)
121{
122    if (index >= (uint32_t)m_profilEntries.getCount())
123        return 0;
124
125    return m_profilEntries[index].invocationCount;
126}
127} // namespace Slang