Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to use Tracy plots directly from Lua via UnsyncedCtrl Spring.LuaTracyPlotConfig and Spring.LuaTracyPlot #1215

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

Beherith
Copy link
Contributor

/*** Initialize a plot in Tracy for use in debugging or profiling
 *
 * @function Spring.LuaTracyPlotConfig
 * @string plotName which should be initialized
 * @string[opt] plotFormatType "Number"|"Percentage"|"Memory", default "Number"
 * @bool[opt] step stepwise chart, default true is stepwise
 * @bool[opt] fill color fill, default false is no fill
 * @number[opt] color unit32 number as BGR color, default white
 * @treturn nil
 */
/*** Update a Tracy Plot with a value
 *
 * @function Spring.LuaTracyPlot
 * @string plotName which LuaPlot should be updated (must have been initialized via LuaTracyPlotConfig)
 * @number plotvalue the number to show on the Tracy plot
 * @treturn nil
 */

I was now quickly able to plot chobby memory usage in a very fine grained way by wrapping a function via debug.sethook(), example below:

local function plotMem()
	if tracy then
		local ramuse = gcinfo()
		Spring.LuaTracyPlot("ChobbyMem",  ramuse)
	end
end
local function GetUserControls(userName,opts)
	debug.sethook(plotMem, 'c r')
	GetUserControlsWrapped(userName, opts)
	debug.sethook()
end

Result:
image

Million thanks to @sprunk !

Beherith and others added 7 commits January 16, 2024 21:56
…otConfig, LuaTracyPlot

LuaTracyPlotConfig(number plotIndex , string plotType, bool step, bool fill, number color)
LuaTracyPlot(number plotIndex, number plotValue)
Plot indices go from 1-9, I could not figure out how to pass a name to the plot. Any help there is welcome!
@Beherith Beherith requested a review from p2004a January 16, 2024 21:42
rts/Lua/LuaUnsyncedCtrl.cpp Outdated Show resolved Hide resolved
rts/Lua/LuaUnsyncedCtrl.cpp Outdated Show resolved Hide resolved
rts/Lua/LuaUnsyncedCtrl.cpp Outdated Show resolved Hide resolved
@sprunk
Copy link
Collaborator

sprunk commented Jan 26, 2024

How tested was this? It doesn't compile.

Edit: fixed 54f90ce

@sprunk
Copy link
Collaborator

sprunk commented Jan 26, 2024

Also, the set was originally there to prevent TracyPlot from being called on names that weren't initialized via TracyPlotConfig but #1215 (comment) seems to say that isn't actually a problem (it will just use default config). So the set can be dropped altogether. I added a commit as well. Feel free to drop any of the last 3 if there's an issue with them.

@p2004a
Copy link
Collaborator

p2004a commented Jan 27, 2024

@sprunk I believe your change is incorrect. Whatever the plot is configured or not and whatever it's fine to use dynamically allocated strings that can be freed are orthogonal.

Tracy in almost all cases is using the pointed to the string literal as identifier. It's passing only the pointer to the worker thread, and then the actual string value is fetched afterwards at some later time. I believe in case of zones, the unique pointer is required, in case of plots the docs say

It is beneficial but not required to use a unique pointer for name string literal (see section 3.1.2 for more details).

Which is the same section that explains the string literals for Zones. Even if the unique pointer for strings was not required, I'm quite sure it must not be memory that can be freed during program runtime.

@sprunk
Copy link
Collaborator

sprunk commented Jan 27, 2024

Thanks, I did a switcheroo and replaced that commit with one that puts your comment in the code.

@@ -212,6 +212,9 @@ bool CLuaIntro::LoadUnsyncedCtrlFunctions(lua_State* L)

REGISTER_SCOPED_LUA_CFUNC(LuaUnsyncedCtrl, SetLogSectionFilterLevel);

REGISTER_SCOPED_LUA_CFUNC(LuaUnsyncedCtrl, LuaTracyPlotConfig);
REGISTER_SCOPED_LUA_CFUNC(LuaUnsyncedCtrl, LuaTracyPlot);
Copy link
Collaborator

@p2004a p2004a Jan 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've realized one more thing, if we want to maintain (And I think we want) that tracing annotations are 0 overhead in release build, those exports should be in #if defined(TRACY_ENABLE) block

The problem is that tracy::LuaRemove calls we have to drop tracing in the release mode, won't delete Spring.LuaTracyPlot calls, so we might need to add our own cleanup like the code in tracy to do that...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relatedly, maybe these should go under the tracy namespace in Lua?

I've seen that the tracy cleanup is actually just a dumb removal of tracy.Blabla from the Lua plaintext code which I expect would break if people did local tBla = tracy.Bla and then used tBla(). And with Spring.Bla there is a heavy cargo cult of localizing functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, what if we just added Spring.LuaTracyPlot to the tracy subtable if tracy is present in system.lua?
So in usage, Spring.LuaTracyPlot would instead be
tracy.LuaTracyPlot()
Would the tracy cleanup stuff also remove this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the tracy cleanup stuff also remove this?

Yes (it would require a one-liner change in the cleanup func to handle the new var but that's trivial)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So no, because we don't own cleanup function code, it lives in the tracy repo.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My preferred solution would still be to have just the bodies of Spring.TracyLuaPlot functions gated within
#if defined(TRACY_ENABLE) blocks, effectively making them near noop's.

  1. Since none of the functions have any return values, it doesn't matter to Lua's perspective
  2. We don't want to modify tracy upstream, as every time we've done that to a library it comes back later to bite us in the ass when it needs to be updated (remember Assimp, SDL, Lua, etc ), so it cannot be placed in the tracy. namespace.

These plotting functions shouldn't be overused too much anyway, so while 100% free is not possible with them, its only a tiny overhead. There are way more egregious wastes of performance littered everywhere else by game developers compared to some empty function calls that provide highly valuable debugging insight when used.

Copy link
Collaborator

@sprunk sprunk Aug 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to modify tracy upstream, as every time we've done that to a library it comes back later to bite us in the ass when it needs to be updated (remember Assimp, SDL, Lua, etc )

But none of those were upstreamed, i.e. we never sent patches to the official repos. We just had a patched internal copy of each of those, and that modified copy then got merge conflicts. The idea here would be to add a new Recoil-side function that wraps over tracy's replacer (without touching tracy itself, so no conflicts) and then actually send patches to the tracy repo (which we never did with the earlier libs).

so it cannot be placed in the tracy. namespace.

We can add to it from outside the tracy lib. Consider rts/Lua/LuaMathExtra.cpp which adds to the built-in Lua math. namespace, completely separate from lib/lua/src/lmathlib.cpp which is what creates the built-in math. namespace. Similarly the tracy. Lua namespace can be created and mostly filled inside the tracy lib somewhere in lib/tracy/blabla, and then we would have rts/Lua/LuaTracyExtra.cpp which adds the others.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to what Sprung said

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I can write a PoC of my ideal solution on the weekend

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is my PoC implementation: #1651

@p2004a @Beherith

@lhog
Copy link
Collaborator

lhog commented Feb 13, 2024

@p2004a can I ask you to decide whether this PR is ready for merge (and press the squash button, if it's)?

@p2004a
Copy link
Collaborator

p2004a commented Feb 18, 2024

I would like the open thread to be resolved somehow™ before merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants