Jump to content
  • Advertisement
Sign in to follow this  
ill

Lockless Message Queue C++

This topic is 2560 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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)?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!