Open Bug 1834848 Opened 2 years ago Updated 1 year ago

Profiling report from 0 A.D. 1v1 AI game

Categories

(Core :: JavaScript Engine: JIT, enhancement, P3)

Firefox 115
enhancement

Tracking

()

UNCONFIRMED

People

(Reporter: wraitii, Unassigned)

References

(Blocks 1 open bug)

Details

Attachments

(1 file)

Steps to reproduce:

I ran an AI 1v1 game of 0 A.D. on SM 115 (this is way upstream of what we have right now but the changes from ESR78 are small).

Using samply and IONPERF, I was able to get a full profiling report including JS code.
The report is 'typical' for an AI 1v1 game. Our AI is coded in javascript, and so is a lot of the engine, so naturally we spend a lot of time in JS functions.

Actual results:

The report shows some obvious patterns which might be interesting for JS-code performance, namely:

  • the Timer::OnUpdate function shows obviously that the GCs dump the Jitted code, but that code is immediately recompiled.
  • This also seems to apply inside of Timer::OnUpdate, e.g. ResourceGatherer.prototype.ResourceGather is first ran on baseline then on Ion. This suggests, to me, that the warmup counters are also reset.

Overall, 0 A.D. spends quite some time in BaselineIC / Baseline / sometimes the interpreter. I believe quite some part from that stems from this GC/Jitting behaviour.

Profiling data from Sample

The Bugbug bot thinks this bug should belong to the 'Core::JavaScript Engine: JIT' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → JavaScript Engine: JIT
Product: Firefox → Core

Thanks for this!

Severity: -- → S3
Priority: -- → P3

Some things I've understood since:

  • We are running shrinking GCs, hence why the JIT data gets thrown out. I think we'll need to change that.
  • The Spectre mitigations are a serious slowdown on our code, as calling C++ from JS is a lot slower with them. I'm also planning to use the configurability of the engine to drop these.

In terms of 'raw overhead', I think our biggest pain point right now is that constructing JS objects from C++ is somewhat slow and awkward, some indicative testing shows that we might actually be faster if we called into JIT-ted code for that.

Another bad-case: we use a lot (thousands) of PersistentRootedValue for the wrappers of our C++ components. These make the microGCs much slower than they need to be.

(In reply to wraitii from comment #0)

The report shows some obvious patterns which might be interesting for JS-code performance, namely:

  • the Timer::OnUpdate function shows obviously that the GCs dump the Jitted code, but that code is immediately recompiled.
  • This also seems to apply inside of Timer::OnUpdate, e.g. ResourceGatherer.prototype.ResourceGather is first ran on baseline then on Ion. This suggests, to me, that the warmup counters are also reset.

Previously we used to keep baseline around, but since we no longer use baseline as a fallback target we might discard it.

It sounds to me that you should be looking at how we handled requestAnimationFrame in SpiderMonkey / Firefox. We have some tricks to prevent GCs and to prevent the code from being GC-ed if it happens in this functions.

Here is a pointer to a field named lastAnimationTime:
https://searchfox.org/mozilla-central/rev/0c2945ad4769e2d4428c72e6ddd78d60eb920394/js/src/gc/GC.cpp#2268

It seems that it can be updated using js::NotifyAnimationActivity.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: