lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

On Saturday 12, Rena wrote:
> I've been working on a Game Boy emulator, which is written mostly as a
> collection of C modules (CPU emulator, memory, renderer, etc) which
> are glued together by a Lua startup script. The script loads the
> modules, connects them together as necessary, loads a game, and sets
> the CPU off running. The frontend uses GTK 3, with C modules
> responsible for pushing images to the screen and reading the
> keyboard/joypad, and Lua (via lgi) running the main loop.
> The gist of the main application loop is:
> local function main()
> 	repeat
> 		gb.cpu:run_frames(frameskip + 1) --execute one or more frames
> 		coroutine.yield()
> 	until shutting_down
> 	Gtk.main_quit()
> end
> local main_thread = coroutine.create(main)
> glib.idle_add(glib.PRIORITY_HIGH_IDLE + 25, --just below redrawing (or
> else it won't redraw)
> 	function() coroutine.resume(main_thread) return true end)
> Gtk.main()
> I was told by a Gnome developer that this is the ideal way to work
> with GTK, versus calling main_loop_do() every frame. This means for
> every emulated frame (60/sec), GTK (C) calls this code (Lua) which
> calls a coroutine (Lua) which calls the CPU core (C). I'm curious if
> this constant switching between Lua and C code, and/or calling and
> yielding a coroutine, is a significant bottleneck. I'm also wondering
> what's a good way to go about profiling this program to find what
> needs optimization.

I would recommend running your program under callgrind [1] and viewing the 
results with kcachegrind [2].  This will help you see if the Lua VM is adding 
a lot of overhead to your emulate-render-loop.

Also why use a coroutine?  Couldn't you do the following:
local function run_frames()
  gb.cpu:run_frames(frameskip + 1) --execute one or more frames
  if shutting_down then
glib.idle_add(glib.PRIORITY_HIGH_IDLE + 25, run_frames)


Robert G. Jakabosky