How to optimize game logic code (very branchy, lots of C API invokes) written in luajit

  • From: 招文勇 <uddwilliam@xxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Fri, 22 Apr 2016 17:04:11 +0800

We're heavily using luajit as major language for our game on Android/iOS.
After months of work we found that it's not easy to implement the whole
game logic in luajit with high performance due to some issues:

1. game logic is very branchy (AI, state machine, complex condition, etc.)
and it's hard to avoid this. This is terrible for a trace compiler.
2. some hot loop need to use exported C API (like game engine API). we try
to limit this but sometimes we have to use it and some of them are not easy
to implement with FFI.
3. we're using object oriented like programing style, and we notice that
this makes BC_TGETS become a performance hotspot (with gprof profiler).
4. we moved some hot code to native language but the performance is still
not good enough. What's worse, this can make hot loop tracing fail
sometimes.

we have to use dynamic language as our major programming language since
it's unable to hot fix code implemented with native language on iOS, and
hot fixing is very important to us. So the only choice for us is to find a
way to optimize our code and make the compiler happy.

So the question is:
1. Is there any tricks to optimize code without removing branchy logic and
make trace compiler happy? For example, using function table to implement
swtich-case instead of using if-else.
2. Since it's unable to enable jit in iOS, is it a good practice to index
table with integer constants instead of using strings to avoid bytecode
TGETS? (self.field1 ====> field1=1; self[field1])
3. It's very easy to get "NYI: register coalescing too complex" error on
ARM device, even in some simple function (not sure if it's inlined). Any
suggestions to avoid this?
4. Any document fully explain how the trace compiler work in detail?

Thanks!

Other related posts: