I know that hundreds of variations of these considerations have been posted all over the net. However, I haven't found anything that adresses my exact problem, so I hope you can help me see the light.
I'm currently toying with 2D game development in Java using OpenGL. The language and graphics library used is not that relevant to my question though as it has a more general character.
I'm attempting to design a general purpose game loop which can be used more or less as is for any game that has moderately heavy graphics (mostly bitmap textures) and possibly even heavier game logic (AI, collision detection, etc).
Basically I'm expecting to maintain a list/array/buffer of objects that can be updated (positions, velocities, and other game related updates) and rendered (textures/frames at updated positions) non stop as smooth and efficiently as possible.
1) One thread for update + rendering
I have tried and discarded a sequential solution using only one thread (well, two when counting user input).
- Calculate changes and update buffer objects
- Render textures at updated positions to backbuffer
- Swap backbuffer to front
Apparently a lot of good computing time is wasted while swap-buffers is blocking on the hardware, which calls for a more efficient solution
2) One thread for update, one for rendering
By splitting the program into an update thread and a rendering thread and synchronizing access to the shared buffer I should be able to ensure a pretty steady framerate. Synchronizing access to the shared buffer can be accomplished in many ways, but they all have one thing in common. They all prohibit thread concurrency. While this may be a fair tradeoff, I'm wondering what makes synchronization necessary.
3) Same as 2, but without synchronization
I do understand many of the problems that can be caused by careless implementation of concurrent threads. The producer/consumer, the readers/writers and similar situations causing potential deadlocks. However, I do not understand why I need to ensure synchronization of the shared data if the following criteria are met (and they should be):
- The render thread can only read from the shared buffer
- The update thread can both read from, and write to the shared buffer (so it is the only 'writer')
- The shared buffer will never be empty nor full while the game is running
- The threads will never sleep
- The rendering does not have to be 100% accurate. If some shared objects have not yet been updated causing them to be one update-step (ie. some 10-20 millisecs) behind other objects no one should ever notice.
-
So... what obvious thing am I missing here? Why do I need the synchronization for this setup?
- Can threads cache data causing problems when not properly synchronized?
- Or can data somehow be garbled if the writing thread is interrupted at an unfortunate time?
- Or are there any general problems with my proposed stategy making it useless?
Any thoughts, comments, or suggestions are most welcome. Or if this particular question has already been addressed elsewhere I would appreciate a reference.