1 year ago

#304248

test-img

mrzacek mrzacek

Implementing Spin lock vs. Win32 Critical section

I'm trying to optimize Win32's CRITICAL_SECTION for more "complex" synchronization primitives, where I don't need the reentrance feature of the critical section. So here's my spin lock so far:

class MSpinLock
{
    volatile LONG X;
public:
    
    void Enter()
    {
        while (1)
        {
            const LONG ret = ::InterlockedExchange(&X, 1);
            if (X == 1 && ret == 0) break;

            MBOOL shouldsleep = 1;
            for (int iter=0; iter<1024; iter++)
            {
                _mm_pause();
                if (X == 0) { shouldsleep = 0; break; };
            };
            if (shouldsleep) ::SwitchToThread();
        };
    };

    //void Exit() { ::InterlockedExchange(&X, 0); };
    void Exit() { X = 0; };
};

The first question is whether the Exit implementation is sufficient like this?

And mainly I started comparing it to critical sections by allocating multiple threads which do something like this:

for (int i=0; i<10000000; i++)
{
    TheLock.Enter();
    DummyVariable++;
    TheLock.Exit();
};

Then just waiting for the threads. It's not exactly scientific test, but does the trick for now apparently - with just a single thread, the threads finish 3x faster compare to using the critical section. But once there are more threads it gets way worse. So apparently when there are concurrent threads, the algorithm starts spending too much time somewhere in the loop, or perhaps the fairness is just too bad. Any ideas how to optimize this?

winapi

critical-section

spinlock

0 Answers

Your Answer

Accepted video resources