Skip to content

Commit

Permalink
Add lua profiler console commands.
Browse files Browse the repository at this point in the history
  • Loading branch information
Neloreck committed Jan 18, 2025
1 parent 9755fbf commit 99838b5
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 52 deletions.
117 changes: 117 additions & 0 deletions src/xrGame/console_commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1992,6 +1992,115 @@ class CCC_UI_Time_Factor : public IConsole_Command
}
};

class CCC_LuaProfiler : public IConsole_Command
{
public:
CCC_LuaProfiler(LPCSTR N) : IConsole_Command(N) { bEmptyArgsHandled = true; };
virtual void Execute(LPCSTR args)
{

if (strstr(cName, "lua_profiler_start_hook_mode") == cName)
{
GEnv.ScriptEngine->m_profiler->startHookMode();
}
else if (strstr(cName, "lua_profiler_start_sampling_mode") == cName)
{
u32 interval = atoi(args);

GEnv.ScriptEngine->m_profiler->startSamplingMode(
interval ? interval : CScriptProfiler::PROFILE_SAMPLING_INTERVAL_DEFAULT);
}
else if (strstr(cName, "lua_profiler_start") == cName)
{
u32 profiler_type = atoi(args);

GEnv.ScriptEngine->m_profiler->start(
(profiler_type ? (CScriptProfilerType)profiler_type : CScriptProfiler::PROFILE_TYPE_DEFAULT));
}
else if (strstr(cName, "lua_profiler_stop") == cName)
{
GEnv.ScriptEngine->m_profiler->stop();
}
else if (strstr(cName, "lua_profiler_reset") == cName)
{
GEnv.ScriptEngine->m_profiler->reset();
}
else if (strstr(cName, "lua_profiler_log") == cName)
{
u32 limit = atoi(args);

GEnv.ScriptEngine->m_profiler->logReport(
limit ? limit : CScriptProfiler::PROFILE_ENTRIES_LOG_LIMIT_DEFAULT);
}
else if (strstr(cName, "lua_profiler_save") == cName)
{
GEnv.ScriptEngine->m_profiler->saveReport();
}
};

void fill_tips(vecTips& tips, u32 /*mode*/) override
{
CScriptProfiler* profiler = GEnv.ScriptEngine->m_profiler;
TStatus status_buffer;


if (strstr(cName, "lua_profiler_start_hook_mode") == cName)
{
// No arguments.
}
else if (strstr(cName, "lua_profiler_start_sampling_mode") == cName)
{
xr_sprintf(status_buffer, "%d (default) [1-%d] - sampling interval",
CScriptProfiler::PROFILE_SAMPLING_INTERVAL_DEFAULT, CScriptProfiler::PROFILE_SAMPLING_INTERVAL_MAX);
tips.push_back(status_buffer);
}
else if (strstr(cName, "lua_profiler_start") == cName)
{
xr_sprintf(status_buffer, "%d - hooks based profiler", CScriptProfilerType::Hook);
tips.push_back(status_buffer);

xr_sprintf(status_buffer, "%d - sampling based profiler", CScriptProfilerType::Sampling);
tips.push_back(status_buffer);
}
else if (strstr(cName, "lua_profiler_stop") == cName)
{
// No arguments.
}
else if (strstr(cName, "lua_profiler_reset") == cName)
{
// No arguments.
}
else if (strstr(cName, "lua_profiler_log") == cName)
{
xr_sprintf(status_buffer, "%d (default) - count of profiling entries to print",
CScriptProfiler::PROFILE_ENTRIES_LOG_LIMIT_DEFAULT, CScriptProfiler::PROFILE_SAMPLING_INTERVAL_MAX);
tips.push_back(status_buffer);
}
else if (strstr(cName, "lua_profiler_save") == cName)
{
// No arguments.
}
}

void Info(TInfo& I) override
{
if (strstr(cName, "lua_profiler_start_hook_mode") == cName)
xr_strcpy(I, "no arguments : start lua script profiling in hook mode");
else if (strstr(cName, "lua_profiler_start_sampling_mode") == cName)
xr_strcpy(I, "integer value in range [1,1000] : start lua script profiling in sampling mode with provided sampling interval");
else if (strstr(cName, "lua_profiler_start") == cName)
xr_strcpy(I, "integer value in range [0,2] : start lua script profiling in provided mode");
else if (strstr(cName, "lua_profiler_stop") == cName)
xr_strcpy(I, "no arguments : stop lua script profiling");
else if (strstr(cName, "lua_profiler_reset") == cName)
xr_strcpy(I, "no arguments : reset lua script profiling stats");
else if (strstr(cName, "lua_profiler_log") == cName)
xr_strcpy(I, "integer value : log lua script profiling stats, limit entries with argument");
else if (strstr(cName, "lua_profiler_save") == cName)
xr_strcpy(I, "no arguments : save lua script profiling stats in a file");
}
};

void CCC_RegisterCommands()
{
ZoneScoped;
Expand Down Expand Up @@ -2076,6 +2185,14 @@ void CCC_RegisterCommands()
CMD3(CCC_Mask, "lua_debug", &g_LuaDebug, 1);
#endif // MASTER_GOLD

CMD1(CCC_LuaProfiler, "lua_profiler_start");
CMD1(CCC_LuaProfiler, "lua_profiler_start_sampling_mode");
CMD1(CCC_LuaProfiler, "lua_profiler_start_hook_mode");
CMD1(CCC_LuaProfiler, "lua_profiler_stop");
CMD1(CCC_LuaProfiler, "lua_profiler_reset");
CMD1(CCC_LuaProfiler, "lua_profiler_log");
CMD1(CCC_LuaProfiler, "lua_profiler_save");

#ifdef DEBUG
CMD4(CCC_Integer, "lua_gcstep", &psLUA_GCSTEP, 1, 1000);
CMD3(CCC_Mask, "ai_debug", &psAI_Flags, aiDebug);
Expand Down
28 changes: 12 additions & 16 deletions src/xrScriptEngine/ScriptEngineScript.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
////////////////////////////////////////////////////////////////////////////
// Module : script_engine_script.cpp
// Created : 25.12.2002
// Modified : 13.05.2004
// Author : Dmitriy Iassenev
// Description : ALife Simulator script engine export
// Module : script_engine_script.cpp
// Created : 25.12.2002
// Modified : 13.05.2004
// Author : Dmitriy Iassenev
// Description : ALife Simulator script engine export
////////////////////////////////////////////////////////////////////////////

#include "pch.hpp"
Expand Down Expand Up @@ -175,11 +175,7 @@ SCRIPT_EXPORT(CScriptEngine, (),
{
GEnv.ScriptEngine->m_profiler->isActive();
}),
def("start", +[]()
{
GEnv.ScriptEngine->m_profiler->start();
}),
def("start", +[](CScriptProfilerType hook_type)
def("start", +[](CScriptProfilerType hook_type = CScriptProfilerType::None)
{
GEnv.ScriptEngine->m_profiler->start(hook_type);
}),
Expand All @@ -199,9 +195,9 @@ SCRIPT_EXPORT(CScriptEngine, (),
{
GEnv.ScriptEngine->m_profiler->reset();
}),
def("log_report", +[]()
def("log_report", +[](u32 entries_limit = CScriptProfiler::PROFILE_ENTRIES_LOG_LIMIT_DEFAULT)
{
GEnv.ScriptEngine->m_profiler->logReport();
GEnv.ScriptEngine->m_profiler->logReport(entries_limit);
}),
def("save_report", +[]()
{
Expand All @@ -210,12 +206,12 @@ SCRIPT_EXPORT(CScriptEngine, (),
];

/**
* Exports injected from tracy profiler:
* Exports injected from tracy profiler:
*
* https://github.com/wolfpld/tracy/blob/da60684b9f61b34afa5aa243a7838d6e79096783/manual/tracy.tex#L1932
* https://github.com/wolfpld/tracy/blob/da60684b9f61b34afa5aa243a7838d6e79096783/public/tracy/TracyLua.hpp#L18
*
* global tracy {
* global tracy {
* function ZoneBegin;
* function ZoneBeginN;
* function ZoneBeginS;
Expand All @@ -224,6 +220,6 @@ SCRIPT_EXPORT(CScriptEngine, (),
* function ZoneText;
* function ZoneName;
* function Message;
* }
*/
* }
*/
});
82 changes: 56 additions & 26 deletions src/xrScriptEngine/script_profiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,34 @@ CScriptProfiler::~CScriptProfiler()
m_engine = nullptr;
}

shared_str CScriptProfiler::getTypeString() const
{
switch (m_profiler_type)
{
case CScriptProfilerType::None:
return "None";
case CScriptProfilerType::Hook:
return "Hook";
case CScriptProfilerType::Sampling:
return "Sampling";
default: NODEFAULT;
}
};

u32 CScriptProfiler::getRecordsCount() const
{
switch (m_profiler_type)
{
case CScriptProfilerType::None:
return 0;
case CScriptProfilerType::Hook:
return m_hook_profiling_portions.size();
case CScriptProfilerType::Sampling:
return m_sampling_profiling_log.size();
default: NODEFAULT;
}
};

void CScriptProfiler::start(CScriptProfilerType profiler_type)
{
switch (profiler_type)
Expand All @@ -37,7 +65,9 @@ void CScriptProfiler::start(CScriptProfilerType profiler_type)
case CScriptProfilerType::None:
Msg("[P] Tried to start none type profiler");
return;
default: NODEFAULT;
default:
Msg("[P] Tried to start unknown type (%d) profiler", profiler_type);
return;
}
}

Expand Down Expand Up @@ -146,21 +176,21 @@ void CScriptProfiler::reset()
m_sampling_profiling_log.clear();
}

void CScriptProfiler::logReport()
void CScriptProfiler::logReport(u32 entries_limit)
{
switch (m_profiler_type)
{
case CScriptProfilerType::Hook:
return logHookReport();
case CScriptProfilerType::Sampling:
return logSamplingReport();
default:
Msg("[P] No active profiling data to report");
return;
case CScriptProfilerType::Hook:
return logHookReport(entries_limit);
case CScriptProfilerType::Sampling:
return logSamplingReport(entries_limit);
default:
Msg("[P] No active profiling data to report");
return;
}
}

void CScriptProfiler::logHookReport()
void CScriptProfiler::logHookReport(u32 entries_limit)
{
if (m_hook_profiling_portions.empty())
{
Expand All @@ -186,7 +216,7 @@ void CScriptProfiler::logHookReport()
Msg("[P] ==================================================================");
Msg("[P] = By calls duration:");
Msg("[P] ==================================================================");
Msg("[P] [idx] sum sum%% | calls avg | trace");
Msg("[P] [idx] sum sum%% avg | calls | trace");

u64 index = 0;

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

for (auto it = entries.begin(); it != entries.end(); it++)
{
if (index >= CScriptProfiler::PROFILE_ENTRIES_LOG_LIMIT)
if (index >= entries_limit)
break;

Msg("[P] [%3d] %9.3f ms %5.2f%% | %9d %9.3f ms | %s", index, (*it)->second.duration() / 1000.0,
((f64)(*it)->second.duration() * 100.0) / (f64)total_duration, (*it)->second.count(),
(f64)(*it)->second.duration() / (f64)(*it)->second.count() / 1000.0, (*it)->first.c_str());
Msg("[P] [%3d] %9.3f ms %5.2f%% %9.3f ms | %9d | %s", index, (*it)->second.duration() / 1000.0,
((f64)(*it)->second.duration() * 100.0) / (f64)total_duration,
(f64)(*it)->second.duration() / (f64)(*it)->second.count() / 1000.0, (*it)->second.count(),
(*it)->first.c_str());

index += 1;
}
Expand All @@ -217,7 +248,7 @@ void CScriptProfiler::logHookReport()

for (auto it = entries.begin(); it != entries.end(); it++)
{
if (index >= CScriptProfiler::PROFILE_ENTRIES_LOG_LIMIT)
if (index >= entries_limit)
break;

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

void CScriptProfiler::logSamplingReport()
void CScriptProfiler::logSamplingReport(u32 entries_limit)
{
if (m_sampling_profiling_log.empty())
{
Expand Down Expand Up @@ -276,7 +307,7 @@ void CScriptProfiler::logSamplingReport()

for (auto it = entries.begin(); it != entries.end(); it++)
{
if (index >= CScriptProfiler::PROFILE_ENTRIES_LOG_LIMIT)
if (index >= entries_limit)
break;

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

Msg("[P] ==================================================================");
Msg("[P] = Total samples: %d", total_count);
Msg("[P] = Total function calls duration: %d ms (approximate)", total_count * m_sampling_profile_interval);
Msg("[P] ==================================================================");

FlushLog();
Expand All @@ -297,13 +327,13 @@ void CScriptProfiler::saveReport()
{
switch (m_profiler_type)
{
case CScriptProfilerType::Hook:
return saveHookReport();
case CScriptProfilerType::Sampling:
return saveSamplingReport();
default:
Msg("[P] No active profiling data to save report");
return;
case CScriptProfilerType::Hook:
return saveHookReport();
case CScriptProfilerType::Sampling:
return saveSamplingReport();
default:
Msg("[P] No active profiling data to save report");
return;
}
}

Expand Down
Loading

0 comments on commit 99838b5

Please sign in to comment.