Closed junkdog closed 10 years ago
I want cool sounding issues like this in my projects.
Mathematicians seized all cool terminology, only leaving isolated words for the rest of us.
That said, I figured out a way of reducing artemis' overhead by a large amount: simply avoid calling/implementing abstract EntityProcessingSystem#process(Entity)
- when doing it by hand, the benchmarks results improved by 1/3 to 1/4.
Mechanical Sympathy on method invocation costs.
Mathematicians seized all cool terminology, only leaving isolated words for the rest of us.
We steal all our terms from real life anyway. Texture. File. Directory. Object. Code. Machine. I'm sure mathematicians won't mind if we gank a few more.
Mechanical Sympathy is also the name of my ambient space music band.
I'm sure mathematicians won't mind if we gank a few more.
Such as Shinichi Mochizuki's alien arithmetic holomorphic structures?
Mechanical Sympathy is also the name of my ambient space music band.
Cool, have any links?
It was a joke :)
There's been progress, updated description.
There's been progress
pff, where's my GWT support for bytecode weaving, slacker!
Cool beans though! I'll write you up a nice wiki page if you want, it's the perfect leg stretcher for a crunch. ;)
Can you ELI5 a summary? Something like:
pff, where's my GWT support for bytecode weaving, slacker!
When I've figured out how to implement a worldwide kill-switch into JS - maybe then we can populate the web with sane languages.
(There's some experimentation scheduled for sometime after 0.7.0 - need to figure out how to compile bytecode back to java source (lombok does a pretty good job with delombok) plus benchmark GWT; it'll be easy if everything transpires smoothly, but that never happens when breaching the java-javascript barrier)
Can you ELI5 a summary? Something like:
- how does this work,
Normally, when invoking World#process
, an EntityProcessingSystem
is invoked as follows:
EntitySystem#process
: method is declared final so only one implementation - cheap for the JVM to callEntitySystem#process
makes a call to abstract method #processEntities
: since this one has several implementations, method invocation is much slower (10-20x is often cited, but regardless, it's much slower) - though it doesn't really matter since it's only called once per system and tick.EntityProcessingSystem#processEntities
- the most common parent for concrete entity systems - declares protected abstract void process(Entity e);
; as EntityProcessingSystem#process(Entity)
is likely to be one of the most frequently executed methods AND has multiple implementations (one for each concrete entity processing system), the higher method invocation cost builds upEntitySystem#process
: monomorphicEntityProcessingSystem#processEntities
: megamorphicEntityProcessingSystem#process(Entity)
: megamorphic and invoked once per entity per system, every tick.Ideally, we'd like to get rid of the expensive call to EntityProcessingSystem#process(Entity)
,
s/EntityProcessingSystem/EntitySystem
#process(Entity)
as a private method
#process(Entity)
is only declared abstract in EntityProcessingSystem
, we are no longer invoking a polymorphic method; ie, the method is now monomorphic.
- what are the design constraints a user has to consider.
Currently, #process(Entity)
becomes private (there seems to be a slight perf gain from invoking it as a private method, presumably the JVM can omit de-optimization guards in the generated assembly).
It will however be fixed before the issue is closed, probably with an annotation of some sort: so if one needs to invoke #process
from an external class, it should be possible to control.
Also, doesn't work from the CLI tool yet, but it's coming.
- android compatibility/benefits.
Compatible, though I haven't tested it. Not sure how aggressively dalvik JITs stuff or how it does its method dispatch. I'd like to think it'd improve performance, but needs testing.
- Any other weaving goodness currently not advertised?
Nope, apart from making this work with GWT too, but it's further down the line. @PackedWeaver
can likely be optimized without relying on bytecode manipulation.
Interesting! Does the class still report as an instanceof EntityProcessingSystem? I assume not.
Wonder if this even applies to javascript. GWT must jump through some interesting hoops to emulate java classes to begin with.
I've figured out how to implement a worldwide kill-switch into JS
D: Did I mention my crunch is a web based application that will fail horribly without JS. I'm all for a change but this close to a deadline? Thanks for feeding my nightmares! ;)
Does the class still report as an instanceof EntityProcessingSystem? I assume not.
Nope, no traces left of EntityProcessingSystem.
Wonder if this even applies to javascript. GWT must jump through some interesting hoops to emulate java classes to begin with.
It would be possible to inline #process(Entity)
inside #processEntities
, but the bigger win would probably come from supporting @PackedWeaver
, @PooledWeaver
and @Profile
in GWT.
D: Did I mention my crunch is a web based application that will fail horribly without JS. I'm all for a change but this close to a deadline? Thanks for feeding my nightmares! ;)
It should be an occasion for celebration: an opportunity to bring the project to a close before the deadline!
Another constraint: doesn't work with classes imported from external jars, though this is true for all of artemis' weaving, including the matrix. Should probably fix before 0.7.0 - or better: before LD48.
Mind copying over your comments to the wiki? I'm not sure how to grab your markdown. I can cleanup after if you want.
Optimize system tight loops https://github.com/junkdog/artemis-odb/wiki/Megamorphic
Copied.
I've started putting together an overview of what the bytecode weaving and instrumentation facilities provide: there may be some structural changes to the wiki in the next hour or so.
EntityProcessingSystem#process(Entity)
PackedComponent#forEntity(Entity)
Progess update:
Benchmark results
Test: NormalSpeedBenchmark (nvm the name)
Score = average execution time invoking
world.process()
, measured in microseconds.without optimizeEntitySystems
with optimizeEntitySystems
How to enable
Optimization is automatically applied when running with the maven plugin, optionally one can explicitly enable/disable entity system optimizations:
Remaining
EntityProcessingSystem#process
INVOKEVIRTUAL/INVOKESPECIAL depending on usage@PackedWeaver
and PackedComponentMapper optimizations, although probably not related to this issue,