Skip to content

Commit 99838b5

Browse files
committed
Add lua profiler console commands.
1 parent 9755fbf commit 99838b5

File tree

4 files changed

+201
-52
lines changed

4 files changed

+201
-52
lines changed

src/xrGame/console_commands.cpp

+117
Original file line numberDiff line numberDiff line change
@@ -1992,6 +1992,115 @@ class CCC_UI_Time_Factor : public IConsole_Command
19921992
}
19931993
};
19941994

1995+
class CCC_LuaProfiler : public IConsole_Command
1996+
{
1997+
public:
1998+
CCC_LuaProfiler(LPCSTR N) : IConsole_Command(N) { bEmptyArgsHandled = true; };
1999+
virtual void Execute(LPCSTR args)
2000+
{
2001+
2002+
if (strstr(cName, "lua_profiler_start_hook_mode") == cName)
2003+
{
2004+
GEnv.ScriptEngine->m_profiler->startHookMode();
2005+
}
2006+
else if (strstr(cName, "lua_profiler_start_sampling_mode") == cName)
2007+
{
2008+
u32 interval = atoi(args);
2009+
2010+
GEnv.ScriptEngine->m_profiler->startSamplingMode(
2011+
interval ? interval : CScriptProfiler::PROFILE_SAMPLING_INTERVAL_DEFAULT);
2012+
}
2013+
else if (strstr(cName, "lua_profiler_start") == cName)
2014+
{
2015+
u32 profiler_type = atoi(args);
2016+
2017+
GEnv.ScriptEngine->m_profiler->start(
2018+
(profiler_type ? (CScriptProfilerType)profiler_type : CScriptProfiler::PROFILE_TYPE_DEFAULT));
2019+
}
2020+
else if (strstr(cName, "lua_profiler_stop") == cName)
2021+
{
2022+
GEnv.ScriptEngine->m_profiler->stop();
2023+
}
2024+
else if (strstr(cName, "lua_profiler_reset") == cName)
2025+
{
2026+
GEnv.ScriptEngine->m_profiler->reset();
2027+
}
2028+
else if (strstr(cName, "lua_profiler_log") == cName)
2029+
{
2030+
u32 limit = atoi(args);
2031+
2032+
GEnv.ScriptEngine->m_profiler->logReport(
2033+
limit ? limit : CScriptProfiler::PROFILE_ENTRIES_LOG_LIMIT_DEFAULT);
2034+
}
2035+
else if (strstr(cName, "lua_profiler_save") == cName)
2036+
{
2037+
GEnv.ScriptEngine->m_profiler->saveReport();
2038+
}
2039+
};
2040+
2041+
void fill_tips(vecTips& tips, u32 /*mode*/) override
2042+
{
2043+
CScriptProfiler* profiler = GEnv.ScriptEngine->m_profiler;
2044+
TStatus status_buffer;
2045+
2046+
2047+
if (strstr(cName, "lua_profiler_start_hook_mode") == cName)
2048+
{
2049+
// No arguments.
2050+
}
2051+
else if (strstr(cName, "lua_profiler_start_sampling_mode") == cName)
2052+
{
2053+
xr_sprintf(status_buffer, "%d (default) [1-%d] - sampling interval",
2054+
CScriptProfiler::PROFILE_SAMPLING_INTERVAL_DEFAULT, CScriptProfiler::PROFILE_SAMPLING_INTERVAL_MAX);
2055+
tips.push_back(status_buffer);
2056+
}
2057+
else if (strstr(cName, "lua_profiler_start") == cName)
2058+
{
2059+
xr_sprintf(status_buffer, "%d - hooks based profiler", CScriptProfilerType::Hook);
2060+
tips.push_back(status_buffer);
2061+
2062+
xr_sprintf(status_buffer, "%d - sampling based profiler", CScriptProfilerType::Sampling);
2063+
tips.push_back(status_buffer);
2064+
}
2065+
else if (strstr(cName, "lua_profiler_stop") == cName)
2066+
{
2067+
// No arguments.
2068+
}
2069+
else if (strstr(cName, "lua_profiler_reset") == cName)
2070+
{
2071+
// No arguments.
2072+
}
2073+
else if (strstr(cName, "lua_profiler_log") == cName)
2074+
{
2075+
xr_sprintf(status_buffer, "%d (default) - count of profiling entries to print",
2076+
CScriptProfiler::PROFILE_ENTRIES_LOG_LIMIT_DEFAULT, CScriptProfiler::PROFILE_SAMPLING_INTERVAL_MAX);
2077+
tips.push_back(status_buffer);
2078+
}
2079+
else if (strstr(cName, "lua_profiler_save") == cName)
2080+
{
2081+
// No arguments.
2082+
}
2083+
}
2084+
2085+
void Info(TInfo& I) override
2086+
{
2087+
if (strstr(cName, "lua_profiler_start_hook_mode") == cName)
2088+
xr_strcpy(I, "no arguments : start lua script profiling in hook mode");
2089+
else if (strstr(cName, "lua_profiler_start_sampling_mode") == cName)
2090+
xr_strcpy(I, "integer value in range [1,1000] : start lua script profiling in sampling mode with provided sampling interval");
2091+
else if (strstr(cName, "lua_profiler_start") == cName)
2092+
xr_strcpy(I, "integer value in range [0,2] : start lua script profiling in provided mode");
2093+
else if (strstr(cName, "lua_profiler_stop") == cName)
2094+
xr_strcpy(I, "no arguments : stop lua script profiling");
2095+
else if (strstr(cName, "lua_profiler_reset") == cName)
2096+
xr_strcpy(I, "no arguments : reset lua script profiling stats");
2097+
else if (strstr(cName, "lua_profiler_log") == cName)
2098+
xr_strcpy(I, "integer value : log lua script profiling stats, limit entries with argument");
2099+
else if (strstr(cName, "lua_profiler_save") == cName)
2100+
xr_strcpy(I, "no arguments : save lua script profiling stats in a file");
2101+
}
2102+
};
2103+
19952104
void CCC_RegisterCommands()
19962105
{
19972106
ZoneScoped;
@@ -2076,6 +2185,14 @@ void CCC_RegisterCommands()
20762185
CMD3(CCC_Mask, "lua_debug", &g_LuaDebug, 1);
20772186
#endif // MASTER_GOLD
20782187

2188+
CMD1(CCC_LuaProfiler, "lua_profiler_start");
2189+
CMD1(CCC_LuaProfiler, "lua_profiler_start_sampling_mode");
2190+
CMD1(CCC_LuaProfiler, "lua_profiler_start_hook_mode");
2191+
CMD1(CCC_LuaProfiler, "lua_profiler_stop");
2192+
CMD1(CCC_LuaProfiler, "lua_profiler_reset");
2193+
CMD1(CCC_LuaProfiler, "lua_profiler_log");
2194+
CMD1(CCC_LuaProfiler, "lua_profiler_save");
2195+
20792196
#ifdef DEBUG
20802197
CMD4(CCC_Integer, "lua_gcstep", &psLUA_GCSTEP, 1, 1000);
20812198
CMD3(CCC_Mask, "ai_debug", &psAI_Flags, aiDebug);

src/xrScriptEngine/ScriptEngineScript.cpp

+12-16
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
////////////////////////////////////////////////////////////////////////////
2-
// Module : script_engine_script.cpp
3-
// Created : 25.12.2002
4-
// Modified : 13.05.2004
5-
// Author : Dmitriy Iassenev
6-
// Description : ALife Simulator script engine export
2+
// Module : script_engine_script.cpp
3+
// Created : 25.12.2002
4+
// Modified : 13.05.2004
5+
// Author : Dmitriy Iassenev
6+
// Description : ALife Simulator script engine export
77
////////////////////////////////////////////////////////////////////////////
88

99
#include "pch.hpp"
@@ -175,11 +175,7 @@ SCRIPT_EXPORT(CScriptEngine, (),
175175
{
176176
GEnv.ScriptEngine->m_profiler->isActive();
177177
}),
178-
def("start", +[]()
179-
{
180-
GEnv.ScriptEngine->m_profiler->start();
181-
}),
182-
def("start", +[](CScriptProfilerType hook_type)
178+
def("start", +[](CScriptProfilerType hook_type = CScriptProfilerType::None)
183179
{
184180
GEnv.ScriptEngine->m_profiler->start(hook_type);
185181
}),
@@ -199,9 +195,9 @@ SCRIPT_EXPORT(CScriptEngine, (),
199195
{
200196
GEnv.ScriptEngine->m_profiler->reset();
201197
}),
202-
def("log_report", +[]()
198+
def("log_report", +[](u32 entries_limit = CScriptProfiler::PROFILE_ENTRIES_LOG_LIMIT_DEFAULT)
203199
{
204-
GEnv.ScriptEngine->m_profiler->logReport();
200+
GEnv.ScriptEngine->m_profiler->logReport(entries_limit);
205201
}),
206202
def("save_report", +[]()
207203
{
@@ -210,12 +206,12 @@ SCRIPT_EXPORT(CScriptEngine, (),
210206
];
211207

212208
/**
213-
* Exports injected from tracy profiler:
209+
* Exports injected from tracy profiler:
214210
*
215211
* https://github.com/wolfpld/tracy/blob/da60684b9f61b34afa5aa243a7838d6e79096783/manual/tracy.tex#L1932
216212
* https://github.com/wolfpld/tracy/blob/da60684b9f61b34afa5aa243a7838d6e79096783/public/tracy/TracyLua.hpp#L18
217213
*
218-
* global tracy {
214+
* global tracy {
219215
* function ZoneBegin;
220216
* function ZoneBeginN;
221217
* function ZoneBeginS;
@@ -224,6 +220,6 @@ SCRIPT_EXPORT(CScriptEngine, (),
224220
* function ZoneText;
225221
* function ZoneName;
226222
* function Message;
227-
* }
228-
*/
223+
* }
224+
*/
229225
});

src/xrScriptEngine/script_profiler.cpp

+56-26
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,34 @@ CScriptProfiler::~CScriptProfiler()
2424
m_engine = nullptr;
2525
}
2626

27+
shared_str CScriptProfiler::getTypeString() const
28+
{
29+
switch (m_profiler_type)
30+
{
31+
case CScriptProfilerType::None:
32+
return "None";
33+
case CScriptProfilerType::Hook:
34+
return "Hook";
35+
case CScriptProfilerType::Sampling:
36+
return "Sampling";
37+
default: NODEFAULT;
38+
}
39+
};
40+
41+
u32 CScriptProfiler::getRecordsCount() const
42+
{
43+
switch (m_profiler_type)
44+
{
45+
case CScriptProfilerType::None:
46+
return 0;
47+
case CScriptProfilerType::Hook:
48+
return m_hook_profiling_portions.size();
49+
case CScriptProfilerType::Sampling:
50+
return m_sampling_profiling_log.size();
51+
default: NODEFAULT;
52+
}
53+
};
54+
2755
void CScriptProfiler::start(CScriptProfilerType profiler_type)
2856
{
2957
switch (profiler_type)
@@ -37,7 +65,9 @@ void CScriptProfiler::start(CScriptProfilerType profiler_type)
3765
case CScriptProfilerType::None:
3866
Msg("[P] Tried to start none type profiler");
3967
return;
40-
default: NODEFAULT;
68+
default:
69+
Msg("[P] Tried to start unknown type (%d) profiler", profiler_type);
70+
return;
4171
}
4272
}
4373

@@ -146,21 +176,21 @@ void CScriptProfiler::reset()
146176
m_sampling_profiling_log.clear();
147177
}
148178

149-
void CScriptProfiler::logReport()
179+
void CScriptProfiler::logReport(u32 entries_limit)
150180
{
151181
switch (m_profiler_type)
152182
{
153-
case CScriptProfilerType::Hook:
154-
return logHookReport();
155-
case CScriptProfilerType::Sampling:
156-
return logSamplingReport();
157-
default:
158-
Msg("[P] No active profiling data to report");
159-
return;
183+
case CScriptProfilerType::Hook:
184+
return logHookReport(entries_limit);
185+
case CScriptProfilerType::Sampling:
186+
return logSamplingReport(entries_limit);
187+
default:
188+
Msg("[P] No active profiling data to report");
189+
return;
160190
}
161191
}
162192

163-
void CScriptProfiler::logHookReport()
193+
void CScriptProfiler::logHookReport(u32 entries_limit)
164194
{
165195
if (m_hook_profiling_portions.empty())
166196
{
@@ -186,7 +216,7 @@ void CScriptProfiler::logHookReport()
186216
Msg("[P] ==================================================================");
187217
Msg("[P] = By calls duration:");
188218
Msg("[P] ==================================================================");
189-
Msg("[P] [idx] sum sum%% | calls avg | trace");
219+
Msg("[P] [idx] sum sum%% avg | calls | trace");
190220

191221
u64 index = 0;
192222

@@ -195,12 +225,13 @@ void CScriptProfiler::logHookReport()
195225

196226
for (auto it = entries.begin(); it != entries.end(); it++)
197227
{
198-
if (index >= CScriptProfiler::PROFILE_ENTRIES_LOG_LIMIT)
228+
if (index >= entries_limit)
199229
break;
200230

201-
Msg("[P] [%3d] %9.3f ms %5.2f%% | %9d %9.3f ms | %s", index, (*it)->second.duration() / 1000.0,
202-
((f64)(*it)->second.duration() * 100.0) / (f64)total_duration, (*it)->second.count(),
203-
(f64)(*it)->second.duration() / (f64)(*it)->second.count() / 1000.0, (*it)->first.c_str());
231+
Msg("[P] [%3d] %9.3f ms %5.2f%% %9.3f ms | %9d | %s", index, (*it)->second.duration() / 1000.0,
232+
((f64)(*it)->second.duration() * 100.0) / (f64)total_duration,
233+
(f64)(*it)->second.duration() / (f64)(*it)->second.count() / 1000.0, (*it)->second.count(),
234+
(*it)->first.c_str());
204235

205236
index += 1;
206237
}
@@ -217,7 +248,7 @@ void CScriptProfiler::logHookReport()
217248

218249
for (auto it = entries.begin(); it != entries.end(); it++)
219250
{
220-
if (index >= CScriptProfiler::PROFILE_ENTRIES_LOG_LIMIT)
251+
if (index >= entries_limit)
221252
break;
222253

223254
Msg("[P] [%3d] %9d %5.2f%% | %s", index, (*it)->second.count(),
@@ -234,7 +265,7 @@ void CScriptProfiler::logHookReport()
234265
FlushLog();
235266
}
236267

237-
void CScriptProfiler::logSamplingReport()
268+
void CScriptProfiler::logSamplingReport(u32 entries_limit)
238269
{
239270
if (m_sampling_profiling_log.empty())
240271
{
@@ -276,7 +307,7 @@ void CScriptProfiler::logSamplingReport()
276307

277308
for (auto it = entries.begin(); it != entries.end(); it++)
278309
{
279-
if (index >= CScriptProfiler::PROFILE_ENTRIES_LOG_LIMIT)
310+
if (index >= entries_limit)
280311
break;
281312

282313
Msg("[P] [%3d] %9d %5.2f%% | %s", index, (*it)->second.m_samples,
@@ -287,7 +318,6 @@ void CScriptProfiler::logSamplingReport()
287318

288319
Msg("[P] ==================================================================");
289320
Msg("[P] = Total samples: %d", total_count);
290-
Msg("[P] = Total function calls duration: %d ms (approximate)", total_count * m_sampling_profile_interval);
291321
Msg("[P] ==================================================================");
292322

293323
FlushLog();
@@ -297,13 +327,13 @@ void CScriptProfiler::saveReport()
297327
{
298328
switch (m_profiler_type)
299329
{
300-
case CScriptProfilerType::Hook:
301-
return saveHookReport();
302-
case CScriptProfilerType::Sampling:
303-
return saveSamplingReport();
304-
default:
305-
Msg("[P] No active profiling data to save report");
306-
return;
330+
case CScriptProfilerType::Hook:
331+
return saveHookReport();
332+
case CScriptProfilerType::Sampling:
333+
return saveSamplingReport();
334+
default:
335+
Msg("[P] No active profiling data to save report");
336+
return;
307337
}
308338
}
309339

0 commit comments

Comments
 (0)