On Friday, 2 January 2015 at 18:52:11 UTC, Benjamin Thaut wrote:
Am 02.01.2015 um 19:45 schrieb Vlad Levenfeld:
My personal favorite method is to use the primitives in
core.atomic with
a double or triple buffer. To double buffer, keep two buffers
in an
array (data[][] or something) and an integer index that points
to the
active buffer, then use atomicStore to update active buffer
index when
you want to swap.
Triple buffering can improve runtime performance at the cost
of more
memory, and in this case you will need two indices and two
swap methods,
one for the producer and another for the consumer. I use cas
with a
timed sleep to update the indices in this case.
Take it with a grain of salt, I'm far from a pro, but this has
worked
well for me in the past. I can post some example code if you
need it.
I have to agree with Vlad here. The usual way is to do double
buffering. So you have two buffers which hold all the data that
the physics simulation passes to the game logic. While the
physics simulation is computing the next frame, the game logic
can use the results from the last frame. The only point where
sinchronisation is neccessary is when swapping the buffers. You
have to ensure that both the game logic and the physics thread
are done with their current buffer and then sawp them. The only
downside of this approach is, that you will get a small delay
(usually the time taken for 1 frame) into the data you pass
this way. Sometimes this approach is called the "exractor
pattern". I use it to pass data from the game simulation to the
renderer, so the renderer can render in paralell with the game
simulation computing the next frame. You can find a example of
my double buffered solution here:
https://github.com/Ingrater/Spacecraft/blob/master/game/sources/renderer/extractor.d
I had tripple buffering up and running at some point, but I
went back to double buffering, because tripple buffering can
cause micro lags and you don't want that.
Kind Regards
Benjamin Thaut
Right, I've been looking at core.atomic, but it has very little
documentation, and it's territory I haven't explored, yet. Any
chance of some pointers along the way?