Multi-threading and Mutexes

Hi

I'm programming a multi-threaded application and to make the data thread-safe I use mutexes. To maximize performance, which is more important to minimize? The time I have the locks on or the number of acquires/releases in the program?
I am really concerned about the acquire/release time. I am feeling that it's huge. I don't really know actually. But from google I got the idea that it is the time between acquire and release that is important.
The duration of the lock (the time between acquire and release) would be more important because this is the critical section that would be most likely to bottleneck your application.

If the duration of the lock is short then threads have a chance to stagger themselves effectively getting the most amount of performance possible. If the lock duration is long then all threads pause and you effectively end up with a single threaded program.

I see. But,
how much should I concerned about the "on-off". Am I free to start spawning mutexes here and there as long as they are 1-2 lines of code length?
The length of code isn't relevant. There is an overhead yes, but it's not very big. It'd be one of the last optimisations you'd consider. Getting your algorithms correct so they can be run parallel without huge bottlenecks in synchronisation is much harder.
Ok, first of all, thank you for your replies
But I am afraid I wasn't very clear on what I want to know.
Imagine a function that maximize the performance:

Performance = a / (LengthOfCodeInsideMutexes*w1 + MutexesOnOff*w2)

I'd like to understand how "heavy" are these parts in an application. Their weights if you like. Of course these are not specific numbers. I looking just for their general image.
I understand what a bottleneck is, I do know that I have to avoid them(I will know how on time) and of course I know that the algorithms must be correct.
I'm just asking for something very specific.
Out of interest, is there a reason why you have to use a mutex rather than a critical section?

(If you're talking about using mutexes to protect data from access by different threads of the same Win32/Win64 process, then you should probably be using a critical section instead.)

Andy
@andywestken
Yes, very interesting point, I don't really know why I picked mutexes. I think I read somewhere that mutexes are faster (I also got this idea from reading implementation details on both). And there is also the fact that you can't know if a critical section is abandoned.
Apart from my main question, why do you think I should pick critical sections?
why do you think I should pick critical sections?

Because they're faster.

From: Critical Section vs. Mutex
http://blogs.msdn.com/b/ce_base/archive/2007/03/26/critical-section-vs-mutex.aspx

Now to highlight the differences: In general, mutex objects are more CPU intensive and slower to use than critical sections due to a larger amount of bookkeeping, and the deep execution path into the kernel taken to acquire a mutex. The equivalent functions for accessing a critical section remain in thread context, and consist of merely checking and incrementing/decrementing lock-count related data. This makes critical sections light weight, fast, and easy to use for thread synchronization within a process. The primary benefit of using a mutex object is that a mutex can be named and shared across process boundaries.

I've very rarely seen or used a mutex in the code bases I've worked on, except the rare occasions where was a need to synchronize with another process.

When it comes to abandoned critical sections: I guess I don't feel a need to worry about the. If another process dies then it's perfectly safe to continue, but if one of my own process's threads vanishes, then somethings badly wrong. The last thing I would feel the need to worry about would be a criitical section.

Andy

Last edited on
I see. I had the exact opposite idea from this article.
Thanks a lot. And it also answers my main question(I think). It's quite light to just open/close the critical section, just don't keep it too long acquired to avoid bottlenecks.
Just to get the idea of what I'm trying to do:
I have a connected list in my multi-threaded application. The add/remove/read functions of the list can be accessed from 2-3 threads and I want to avoid conflicts. But the way I'm thinking it, there are a lot of situations that I need to acquire/release a mutex just to change a simple ToNext pointer and this made me think. I was afraid that the over-use of the acquire/release of the mutex will slow down the app. But I get that this is toleratable with critical sections, and also neccessary.
Last edited on
I see. I had the exact opposite idea from this article.

Which article are you referring to? I've not seen an article which disagrees with the quote I posted previously, so I'm quite curious to see it.

Andy

PS Microsoft say of Critical Sections, "a slightly faster, more efficient mechanism"...

Event, mutex, and semaphore objects can also be used in a single-process application, but critical section objects provide a slightly faster, more efficient mechanism for mutual-exclusion synchronization (a processor-specific test and set instruction).

From: Critical Section Objects
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682530%28v=vs.85%29.aspx

But the following Intel article gives these comparative timings (quite a few %...)

Mutexes                 39,880 ms.
Critical sections        1,889 ms.
Interlocked functions      944 ms.
No locks                    70 ms.

Choosing Between Synchronization Primitives
http://software.intel.com/en-us/articles/choosing-between-synchronization-primitives
Last edited on
kalkas wrote:
But the way I'm thinking it, there are a lot of situations that I need to acquire/release a mutex just to change a simple ToNext pointer and this made me think. I was afraid that the over-use of the acquire/release of the mutex will slow down the app. But I get that this is toleratable with critical sections, and also neccessary.



Then in this situation you don't need a mutex or a critical section, using Interlocked* family of functions is exactly what you need.
@andywestken
No, this is a mistunderstanding. I meant I had opposite idea from(or than) the article you posted. Sorry, I'm not native english speaker.
I was probably learned it wrong, your post clear it out for me.
And, indeed, critical sections are much faster than mutexes.

@modoran
Yes, I passed from the Interlocked functions. My timing problem is more (I don't know how to put this) time lasting than a single operation on a single variable collission. I want to prevent some operations to happen while some other specific operations are in progress.
Last edited on
Topic archived. No new replies allowed.