Lockless Message Queue C++

Started by
4 comments, last by ill 12 years, 4 months ago
I was looking for an implementation of a lockless message queue to avoid stalling when threads communicate with each other.

One really useful thing would be a message queue around my logging system. Instead of putting a critical section in the logging function, put the logging on a message queue. The logger will consume messages as fast as it can and log things in the correct order.

Another thing I need this for is the message passing system for the tasks that run in the game loop. The tasks compute AI and all that stuff and then everything synchronizes at the end of a game tick. I don't want locks when entities have to say "I'm now at position (x, y, z)"

Basic idea is in this Intel article
Designing framework of a parallel game engine

I looked at boost::concurrent::message_queue. That one isn't as light weight as I would need it to be.

These are the best articles I found about implementing lockless queues:
Writing Lock-Free Code: A Corrected Queue
Writing a Generalized Concurrent Queue

The thing that has me worried is dealing with padding for the cache. I'm trying to make the engine cross platform and I don't want to deal with such low level platform specific things. I'm really hoping someone has a properly implemented message queue out there that actually works well. I don't want to write a crappy message queue that actually makes performance worse or something. This is more or less my first time getting into hardcore threading besides what we did back in school with pthreads here and there.
Advertisement
You might consider looking at the code, design, etc. here for an inspiration: http://tim.klingt.org/boost_lockfree/
It recently got accepted, although there were some issue w.r.t. naming: http://lists.boost.org/boost-announce/2011/08/0331.php
I've had success with this one before. It is bounded, so what I tend to do is have the enqueue-ing thread help out with processing if insertion fails (very rare in my case).

As for padding, "#define CACHE_LINE_BYTE_SIZE 64" will let you get on with things. If it proves to be insufficient for another platform, a sprinkling of "#ifdef (OBSCURE_PLATFORM)" will fix that.

With that said, are you sure you really need a lock-free queue? If you're already composing messages in to something like std::string, CString, etc, or even "new char[n]", it's likely that you'll already be locking implicitly on the allocator. If what you really want is merely a really really fast queue, it might be worth considering something simpler.

Have you also considered that it might be a good idea to write out log data immediately to risk losing any on a crash? Do you really expect much contention from multi-threaded logging? Will thread-local logs do the job (that could optionally be combined on process exit)?
Well the logging is just one place I need the queue.

I mostly need it in my message passing code for synching up the game ticks.

I expect there to be a lot of contention for logging in the debug build. The release build will probably have barely any logging and it'll be at times when the engine is loading a level or switching the resolution anyway... I could potentially not care about the logging in that case.

I did hear mention about allocators locking. That might be a problem. Is it best to try to avoid reallocating data all the time in that case? It might be doable for the message passing I'm talking about. Just keep that buffer always preallocated since the start of the level and free it later.

I expect there to be a lot of contention for logging in the debug build. The release build will probably have barely any logging and it'll be at times when the engine is loading a level or switching the resolution anyway... I could potentially not care about the logging in that case.

If I were you I'd start by simply slapping a lock around the log. If it's slow, then consider getting more adventurous.

Is it best to try to avoid reallocating data all the time in that case?[/quote]
That's generally a good idea, yes, unless you have some kind of thread-local allocation scheme. But again, beware of going overboard prematurely.

You might consider looking at the code, design, etc. here for an inspiration: http://tim.klingt.org/boost_lockfree/
It recently got accepted, although there were some issue w.r.t. naming: http://lists.boost.o...011/08/0331.php


Wait so these exist? Or are they planned?

This topic is closed to new replies.

Advertisement