CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 17

Threaded View

  1. #10
    Join Date
    Feb 2009
    Location
    Portland, OR
    Posts
    1,488

    Re: Do I need to worry about a failure in these synchronization APIs?

    Quote Originally Posted by OReubens View Post
    the CS assumes that it'll become available "soon" and starts spinning in a loop. If the CS does indeed come available, you win and code proceeds without a costly context switch. if it doesn't, you loose... because you waited in vain for the CS to become available.
    Yeah, I forgot. It's a very good point about CS. I did some timing analysis and the wait in CS seems to run generally 10 times faster than the WaitForSingleObject on mutex. So if timing is important, then CS is the one to go with. Here's the test:
    Code:
    		#include <intrin.h>      //Needed for __rdtsc()
    
    		ULONGLONG _uiCnt00[100] = {0};
    		ULONGLONG _uiCnt01[100] = {0};
    		ULONGLONG _uiCnt02[100] = {0};
    		ULONGLONG _uiCnt03[100] = {0};
    		ULONGLONG _uiCnt04[100] = {0};
    		ULONGLONG _uiCnt05[100] = {0};
    
    		ULONGLONG _uiCnt10[100] = {0};
    		ULONGLONG _uiCnt11[100] = {0};
    		ULONGLONG _uiCnt12[100] = {0};
    		ULONGLONG _uiCnt13[100] = {0};
    		ULONGLONG _uiCnt14[100] = {0};
    		ULONGLONG _uiCnt15[100] = {0};
    		ULONGLONG _uiCnt16[100] = {0};
    
    		VERIFY(::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL));
    
    		for(int i = 0; i < 100; i++)
    		{
    			CRITICAL_SECTION cs;
    			_uiCnt00[i] = __rdtsc();
    			::InitializeCriticalSection(&cs);
    			_uiCnt01[i] = __rdtsc();
    			::EnterCriticalSection(&cs);
    			_uiCnt02[i] = __rdtsc();
    			::EnterCriticalSection(&cs);
    			_uiCnt03[i] = __rdtsc();
    			::LeaveCriticalSection(&cs);
    			_uiCnt04[i] = __rdtsc();
    			::LeaveCriticalSection(&cs);
    			_uiCnt05[i] = __rdtsc();
    			::DeleteCriticalSection(&cs);
    
    			_uiCnt10[i] = __rdtsc();
    			HANDLE hMutex = ::CreateMutex(NULL, FALSE, NULL);
    
    			_uiCnt11[i] = __rdtsc();
    			::WaitForSingleObject(hMutex, INFINITE);
    			_uiCnt12[i] = __rdtsc();
    			::WaitForSingleObject(hMutex, INFINITE);
    			_uiCnt13[i] = __rdtsc();
    			::ReleaseMutex(hMutex);
    			_uiCnt14[i] = __rdtsc();
    			::ReleaseMutex(hMutex);
    			_uiCnt15[i] = __rdtsc();
    
    			::CloseHandle(hMutex);
    			_uiCnt16[i] = __rdtsc();
    
    			Sleep(1);
    		}
    
    		VERIFY(::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_NORMAL));
    
    		ULONGLONG uiCnt00 = 0;
    		ULONGLONG uiCnt01 = 0;
    		ULONGLONG uiCnt02 = 0;
    		ULONGLONG uiCnt03 = 0;
    		ULONGLONG uiCnt04 = 0;
    		ULONGLONG uiCnt05 = 0;
    
    		ULONGLONG uiCnt10 = 0;
    		ULONGLONG uiCnt11 = 0;
    		ULONGLONG uiCnt12 = 0;
    		ULONGLONG uiCnt13 = 0;
    		ULONGLONG uiCnt14 = 0;
    		ULONGLONG uiCnt15 = 0;
    		ULONGLONG uiCnt16 = 0;
    
    		for(int i = 0; i < 100; i++)
    		{
    			uiCnt00 += _uiCnt00[i];
    			uiCnt01 += _uiCnt01[i];
    			uiCnt02 += _uiCnt02[i];
    			uiCnt03 += _uiCnt03[i];
    			uiCnt04 += _uiCnt04[i];
    			uiCnt05 += _uiCnt05[i];
    
    			uiCnt10 += _uiCnt10[i];
    			uiCnt11 += _uiCnt11[i];
    			uiCnt12 += _uiCnt12[i];
    			uiCnt13 += _uiCnt13[i];
    			uiCnt14 += _uiCnt14[i];
    			uiCnt15 += _uiCnt15[i];
    			uiCnt16 += _uiCnt16[i];
    		}
    
    		uiCnt00 /= 100;
    		uiCnt01 /= 100;
    		uiCnt02 /= 100;
    		uiCnt03 /= 100;
    		uiCnt04 /= 100;
    		uiCnt05 /= 100;
    
    		uiCnt10 /= 100;
    		uiCnt11 /= 100;
    		uiCnt12 /= 100;
    		uiCnt13 /= 100;
    		uiCnt14 /= 100;
    		uiCnt15 /= 100;
    		uiCnt16 /= 100;
    
    
    		_tprintf(_T("CriticalSection:\n")
    			_T("InitializeCriticalSection = %I64d cycles\n")
    			_T("EnterCriticalSection = %I64d cycles\n")
    			_T("EnterCriticalSection = %I64d cycles\n")
    			_T("LeaveCriticalSection = %I64d cycles\n")
    			_T("LeaveCriticalSection = %I64d cycles\n")
    			, 
    			uiCnt01 - uiCnt00,
    			uiCnt02 - uiCnt01,
    			uiCnt03 - uiCnt02,
    			uiCnt04 - uiCnt03,
    			uiCnt05 - uiCnt04
    			);
    
    
    		_tprintf(_T("Mutex:\n")
    			_T("CreateMutex = %I64d cycles\n")
    			_T("WaitForSingleObject = %I64d cycles\n")
    			_T("WaitForSingleObject = %I64d cycles\n")
    			_T("ReleaseMutex = %I64d cycles\n")
    			_T("ReleaseMutex = %I64d cycles\n")
    			_T("CloseHandle = %I64d cycles\n")
    			, 
    			uiCnt11 - uiCnt10,
    			uiCnt12 - uiCnt11,
    			uiCnt13 - uiCnt12,
    			uiCnt14 - uiCnt13,
    			uiCnt15 - uiCnt14,
    			uiCnt16 - uiCnt15
    			);
    and the results:
    CriticalSection:
    InitializeCriticalSection = 2490 cycles
    EnterCriticalSection = 167 cycles
    EnterCriticalSection = 232 cycles
    LeaveCriticalSection = 79 cycles
    LeaveCriticalSection = 190 cycles
    Mutex:
    CreateMutex = 5448 cycles
    WaitForSingleObject = 2330 cycles
    WaitForSingleObject = 1842 cycles
    ReleaseMutex = 1753 cycles
    ReleaseMutex = 2663 cycles
    CloseHandle = 3717 cycles
    Last edited by ahmd; September 11th, 2012 at 03:32 PM. Reason: Forgot to add #include <intrin.h>

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured