
Howard Hinnant:
On Feb 8, 2008, at 5:22 PM, Peter Dimov wrote:
There's no significant difference with critical sections, too. Maybe I'm doing something wrong. :-)
Or this could be a manifestation of the fact that I never really had "hands on" tests with Windows. I have observed that if the contention isn't high, then the algorithm doesn't matter. Does your test have the threads sleeping or otherwise doing independent work? In mine the threads did nothing but fight over the locks.
This is what I tried: #define _WIN32_WINNT 0x500 #include <windows.h> //#include "mutex.cpp" class mutex { private: CRITICAL_SECTION cs_; public: mutex() { InitializeCriticalSection( &cs_ ); } ~mutex() { DeleteCriticalSection( &cs_ ); } void lock() { EnterCriticalSection( &cs_ ); } bool try_lock() { return TryEnterCriticalSection( &cs_ ); } void unlock() { LeaveCriticalSection( &cs_ ); } }; void lock2( mutex & m1, mutex & m2 ) { for( ;; ) { m1.lock(); if( m2.try_lock() ) return; m1.unlock(); //Sleep( 0 ); m2.lock(); if( m1.try_lock() ) return; m2.unlock(); //Sleep( 0 ); } } #include <assert.h> mutex m[ 5 ]; int r[ 5 ]; unsigned __stdcall threadproc( void* pv ) { int k = (int)pv; assert( k >= 0 && k < 5 ); int k2 = (k+1) % 5; for( int i = 0; i < 1000000; ++i ) { lock2( m[ k ], m[ k2 ] ); for( int j = 0; j < 1000; ++j ) { r[ k ] = r[ k ] * 1103515245 + 12345; } m[ k ].unlock(); m[ k2 ].unlock(); } return 0; } #include <iostream> #include <time.h> #include <process.h> int main() { HANDLE h[ 5 ] = { 0 }; time_t t1 = time( 0 ); for( int i = 0; i < 5; ++i ) { h[ i ] = (HANDLE)_beginthreadex( 0, 0, threadproc, (void*)i, 0, 0 ); } for( int i = 0; i < 5; ++i ) { WaitForSingleObject( h[ i ], INFINITE ); CloseHandle( h[ i ] ); } time_t t2 = time( 0 ); std::cout << t2 - t1 << std::endl; }