OpenRA icon indicating copy to clipboard operation
OpenRA copied to clipboard

Poor InflictDamage performance on kills

Open reaperrr opened this issue 10 years ago • 9 comments

I noticed arbitrary lag spikes caused by projectiles.

On my notebook with i5-4210M (and presumably some throttling even in 'performance' mode) the Bullet effect (sometimes Missile, too, but less pronounced) occasionally eats up to 80 ms on RA's shellmap in performance mode (and much more, sometimes over 300(!)ms in balanced/power-saving mode).

And while far less of an issue there, even on my i5-2500 main rig the projectiles cause occasional 10-20ms spikes. Their appearance seems to be quite random, so I wonder whether it's only some specific part of the code that causes this.

A while ago I tried to find the exact cause by disabling the ShouldExplode checks and some effects (contrail, trail) one by one, but none of those improved the situation significantly (if at all).

Those hiccups can be quite annoying on slower systems, so it would be nice if someone managed to track down and get rid of the cause.

Edit: It appears it's not the projectile itself, but the stuff happening on impact (warheads).

reaperrr avatar Aug 23 '15 15:08 reaperrr

I added https://github.com/OpenRA/OpenRA/pull/3741 for desync hunting which from what I learned recently is very expensive. Try removing some ISync interfaces and test again to narrow it down.

Mailaender avatar Aug 23 '15 16:08 Mailaender

https://github.com/OpenRA/OpenRA/blob/bleed/OpenRA.Game/World.cs#L333 or somehow manage to skip decorational effects.

Mailaender avatar Aug 23 '15 16:08 Mailaender

If the perf numbers are from perf.log, they won't include sync time so it's probably not that.

The recorded time is from Bullet.Tick or Missile.Tick, so we need to look there.

I can't recreate any super-slow Bullet or Missile times on my system on bleed, so I can't suggest much. I've noticed Explode can sometimes be a little slow but not drastically so.

Maybe try sticking some perf timers inside various bits of the tick methods and see if you can narrow it down?

RoosterDragon avatar Aug 23 '15 20:08 RoosterDragon

Maybe try sticking some perf timers inside various bits of the tick methods and see if you can narrow it down?

Ok, after some more testing and setting PerfTimers, I can say with certainty that

  • the main problem is indeed power-throttling of my notebook
  • the projectile effect is not the problem, not even the 'shouldExplode' checks, but rather the actual impact.

So it appears the projectiles perform just fine (better than I expected), but all the stuff happening at impact (DamageWarhead, EffectWarhead etc.) seems to add up (probably when many projectiles explode at the same tick).

reaperrr avatar Aug 24 '15 11:08 reaperrr

Yeah the actual explosion is quite expensive.

On the RA shellmap, Bullet.Tick uses 0.9% of total CPU time - but almost all of that is calling Explode which means a fairly hefty lag spike can be possible.

Once you dig through the callstack, 0.6% is being spent in Health.InflictDamage. Inside there, 0.4% is calling ScriptTriggers.Damaged and ScriptTriggers.Killed.

On the C# side there are no major bottlenecks - we'd have to find several small savings to get a meaningful speedup. If the shellmap script can be optimized at all that may help too.

RoosterDragon avatar Oct 24 '15 21:10 RoosterDragon

I'm resurrecting this since impacts that cause one or more actors to die are still rather expensive (I've seen up to 27ms cost on my R5 1600 in a single tick just from Tanya's Colt45 killing some infantry). Needless to say how that will look on a significantly lower-clocked mobile CPU, let alone a Pi.

Like @RoosterDragon said there probably isn't one single thing that can miraculously fix that, but going through the traits that implement INotifyKilled to check whether there is anything that could be optimized further wouldn't hurt, I guess.

reaperrr avatar Sep 20 '18 13:09 reaperrr

Do the perf issues come from the actors dying, being removed from the world, or disposed? My gut feeling is that the problems are in one or both of the last two.

pchote avatar Sep 20 '18 14:09 pchote

As far as I can tell, ~80-90% of the cost comes from notifying the traits that implement INotifyKilled (and then perform whatever they do as part of that). The cost of calling Actor.Dispose() (which should include removal) looks negligible in comparison.

reaperrr avatar Sep 20 '18 15:09 reaperrr

Is this still an issue? I'd assume one would need a new investigation is it was

PunkPun avatar Apr 30 '25 14:04 PunkPun