ProfilerMarker And Burst

When I use ProfilerMarker in a Burst job, I’m having compile issues.

Burst error BC1033: Loading a managed string literal is not supported

It does this in 2 scenarios - if I have it defined like this outside the job in the system like this, it will throw the error in the constructor of the system.

private static readonly ProfilerMarker s_MyMarker= new ProfilerMarker("Marker");

It also yells at me about string literals if I have it inside the ForEach too:

ProfilerMarker marker = new ProfilerMarker("MyMarker");
marker.Begin();
marker.End();

If I specify the marker outside the ForEach, it has no problem.

ProfilerMarker marker = new ProfilerMarker("MyMarker");
Entities.WithAll<>().ForEach(() => {
marker.Begin();
marker.End();
}

Is this right? Am I incurring any kind of performance penalties here? I know the Begin/End are removed in release builds, but we do a lot of iteration and debugging and if I need 10 markers in this job I don’t want to be incurring costs I’m not seeing in the profiler correctly. I’ve hit similar traps before with the older Profile Samples API.

I have no idea of the exact context here, but I know these things:

  • you often must mark code to get good profiling insights

  • a marker inserts extra code and executes it

  • extra code executed is never free

Therefore it seems axiomatic to put it as deep in the inner loop as you need it, but no deeper.

Does all this stuff compile out to nothing in release?

ProfilerMarker functions compile out, yes.

This is Entities, so the ForEach is supposed to be heavy loops where you execute a lot of logic that may need to be profiled.

I’m not concerned with the markers themselves, more so the way they’re being used outside of the lambda. Unity does some compile magic with jobs to make them not like typical C# lambdas, they don’t incur memory cost and such. Burst coverts it to high performance code.

Indeed, this is a known issue. Currently, you can only instantiate a profiler marker in managed and pass it to Burst jobs. That’s what it is doing here implicitly with Entities ForEach.

We hope to fix this in a future release of Burst. It requires a change in the ProfilerMarker API to allow this and we have been talking with the Profiler team to unlock this scenario.

5 Likes

thank you for confirming :slight_smile:

It’s still a problem I assume in 0.16 from my tests

It’s a pain to not be able to do this simple thing :

private static readonly ProfilerMarker ProfileMarkerAskPath = new ProfilerMarker($"{nameof(AIPath)}.{nameof(AskPath)}");

Hope that will be fixe in a near futur :slight_smile:

1 Like