Click to See Complete Forum and Search --> : About using Critical section!


stans
January 5th, 2005, 03:52 AM
I have one class may called ThreadControl, it will create one CComAutoCriticalSection, and 2 more threads class A and B.

Can i write a function in ThreadControl, like Lockcs(), which will lock the CComAutoCriticalSection. Then i pass the pointer of the class ThreadControl to the thread class A and B. instead of pass the pointer of CComAutoCriticalSection to the A and B.

Can it work?? coz i think the ThreadControl is in the main thread, if it is call lock cs, it will means lock the cs in the main thread. am i right? Is there anyway i can implement this kind of function call instead of the passing of CComAutoCriticalSection?

thanks a lot in advance

Andreas Masur
January 5th, 2005, 04:36 AM
[ Moved thread ]

darwen
January 6th, 2005, 05:20 PM
Why are you using CComAutoCriticalSection ?

Secondly, and here's a gem. I don't like CCriticalSection either - or any of the critical section classes or even critical sections in Win32.

Why ?

On high load, I've experienced serious problems with them because of this wonderful thing called 'spin'.

'spin' is what happens when you start a critical section.

It effectively goes into a tight loop trying hard to get access to the lock before giving up.

On a high load system, this can cause excessive (and I mean really excessive) processor time.

I prefer to use an auto-reset event and WaitForSingleObject on that event.

Just thought I'd pass on my advice.

Darwen.

MikeAThon
January 6th, 2005, 08:37 PM
...On high load, I've experienced serious problems with them because of this wonderful thing called 'spin'.

'spin' is what happens when you start a critical section.

It effectively goes into a tight loop trying hard to get access to the lock before giving up.

On a high load system, this can cause excessive (and I mean really excessive) processor time.


"Spin" is available only on multi-processor systems, where its use has been demontrated to remarkably improve multipthreaded performance. The basic idea is simple, if an attempt to obtain a cs fails because another thread has ownership, don't go to a wait state immendiately; rather, try again after a short interval during which the thread simply increments an integer (the "spin count") until a fairly low number like 2000. If the other thread still has ownership, then give up and go into a wait state. On the other hand, if it no longer has ownership, then you've saved significant time because you don't need to go into kernel mode for the wait state.

On single-processor systems, spin is useless and is not employed, for the reason that no matter how long you spin, the other thread cannot release the cs until it gets a new timeslice of processor time. So, it's better to relinquish the remainder of the first thread's timeslice immediately (by going to a kernel wait state) so that the other thread gets going as soon as possible.

I guess this is along-winded way of saying that I disagree with your criticism of spin counting, even if it causes a tight processor loop, since it speeds overall processing.

Mike

OReubens
January 7th, 2005, 12:13 PM
I guess this is along-winded way of saying that I disagree with your criticism of spin counting, even if it causes a tight processor loop, since it speeds overall processing.

I agree, it's one of the best things to have on a multi CPU machine.

But... you have to put it in perspective... A critical section is really intended ONLY for protecting very very short pieces of code. Typically in the order of only a couple dozen to maybe a hundred clockcycles.

On a multi CPU machine, you then get an obvious benefit.
CPU 1 locks the CS and does it's stuff
CPU 2 tries to lock, but fails. Instead of switching to another thread immediately, which would be in the order of several thousand clockcycles. It (by right) assumes that the cs will become available very shortly, so it goes spinning into a loop waiting for the cs to become available anyway. If the CS doesn't become available after a while, it gives up and does a contextswitch anyway, incurring the contextswitch penalty of several thousand CPU cycles.

For added performance, you can even tweak the spincount yourself to best fit the case at hand.


Now, if the code you are protecting with a CS is typically MUCH MUCH longer than the spincount of the CS, you are effectively going to waste cycles. But what do you expect from using something the wrong way :D.
If you have a LONG piece of code you need to protect, don't use a critical section, but use an event or a mutex instead.

Andreas Masur
January 7th, 2005, 12:28 PM
If you have a LONG piece of code you need to protect, don't use a critical section, but use an event or a mutex instead.
Well....in case of a multi-cpu machine this might be right...however, critical sections are much faster than kernel objects such as events or mutexes. Since the spin does not take effect on a single cpu, I do not see why a critical section should not be used instead of a mutex within the same process...since it will simply speed up the application...

OReubens
January 7th, 2005, 01:07 PM
Well....in case of a multi-cpu machine this might be right...however, critical sections are much faster than kernel objects such as events or mutexes. Since the spin does not take effect on a single cpu, I do not see why a critical section should not be used instead of a mutex within the same process...since it will simply speed up the application...


Well.. You got me there :o I just suggested something that goes against the policy I have outlined in the course on multithreading I have been teaching...

The correct approach would be to use InitializeCriticalSectionAndSpinCount() and set a low spincount to avoid having to spin too much and then still incur the contextswitch penalty on top of that. But you may need extra code to do this if you need to support older flavours of Windows (Win95, NT before SP3) since this particular function isn't available on them.
On a multi CPU WinNT (before SP3) using an event for long sections of code is slightly faster on average than the regular critical section with default spin. MultiCPU Win95 is not possible.