Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <intrin.h>
- #include <iostream>
- using namespace std;
- struct ThreadInfo
- {
- HANDLE hSemRun;
- bool fStop;
- HANDLE hEvtReady;
- DWORD volatile *pdwPingPong;
- DWORD dwId;
- DWORDLONG volatile dwlIterations;
- DWORDLONG volatile dwlSwaps;
- DWORDLONG volatile dwlTicks;
- };
- DWORD WINAPI PingPongThread( LPVOID lpvThreadParam );
- void PingPong( DWORD volatile *pdwPingPong, DWORD dwId, DWORDLONG dwlIterations, DWORDLONG &dwlSwaps, DWORDLONG &dwlTicks );
- int main()
- {
- DWORDLONG const ITERATIONS = 100000000;
- HANDLE hSemRun;
- HANDLE ahEvtReady[2];
- ThreadInfo ati[2];
- DWORD dwPingPong;
- HANDLE ahThreads[2];
- SYSTEM_INFO si;
- DWORDLONG dwlAvgTicks;
- DWORDLONG dwlDummySwaps;
- DWORDLONG dwlNonSuccessfulXchgTicks;
- double ticksPerSwap;
- SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS );
- hSemRun = CreateSemaphore( NULL, 0, 2, NULL );
- ahEvtReady[0] = CreateEvent( NULL, FALSE, FALSE, NULL );
- ahEvtReady[1] = CreateEvent( NULL, FALSE, FALSE, NULL );
- ati[0].hSemRun = hSemRun;
- ati[1].hSemRun = hSemRun;
- ati[0].hEvtReady = ahEvtReady[0];
- ati[1].hEvtReady = ahEvtReady[1];
- ati[0].fStop = false;
- ati[1].fStop = false;
- ati[0].pdwPingPong = &dwPingPong;
- ati[1].pdwPingPong = &dwPingPong;
- ati[0].dwId = 0;
- ati[1].dwId = 1;
- ati[0].dwlIterations = 100000000;
- ati[1].dwlIterations = 100000000;
- ahThreads[0] = CreateThread( NULL, 0, PingPongThread, &ati[0], 0, NULL );
- ahThreads[1] = CreateThread( NULL, 0, PingPongThread, &ati[1], 0, NULL );
- SetThreadPriority( ahThreads[0], THREAD_PRIORITY_HIGHEST );
- SetThreadPriority( ahThreads[1], THREAD_PRIORITY_HIGHEST );
- SetThreadAffinityMask( ahThreads[0], 1 );
- GetSystemInfo( &si );
- for( unsigned processor = 1; processor != (unsigned)si.dwNumberOfProcessors; processor++ )
- {
- SetThreadAffinityMask( ahThreads[1], (DWORD_PTR)1 << processor );
- ReleaseSemaphore( hSemRun, 2, NULL );
- WaitForSingleObject( ahEvtReady[0], INFINITE );
- WaitForSingleObject( ahEvtReady[1], INFINITE );
- //WaitForMultipleObjects( 2, ahEvtReady, TRUE, INFINITE ); // doesn't work; don't know why
- dwlAvgTicks = (ati[0].dwlTicks + ati[1].dwlTicks) / 2;
- dwPingPong = 0;
- PingPong( &dwPingPong, 1, ITERATIONS - ati[0].dwlSwaps, dwlDummySwaps, dwlNonSuccessfulXchgTicks );
- ticksPerSwap = (double)(LONGLONG)(dwlAvgTicks - dwlNonSuccessfulXchgTicks) / (LONGLONG)ati[0].dwlSwaps;
- cout << "processor 0 and processor " << processor << ": " << ticksPerSwap << endl;
- }
- ati[0].fStop = true;
- ati[1].fStop = true;
- ReleaseSemaphore( hSemRun, 2, NULL );
- WaitForMultipleObjects( 2, ahThreads, TRUE, INFINITE );
- return 0;
- }
- DWORD WINAPI PingPongThread( LPVOID lpvThreadParam )
- {
- ThreadInfo *pti = (ThreadInfo *)lpvThreadParam;
- DWORDLONG dwlSwaps;
- DWORDLONG dwlTicks;
- for( ; ; )
- {
- WaitForSingleObject( pti->hSemRun, INFINITE );
- if( pti->fStop )
- break;
- PingPong( pti->pdwPingPong, pti->dwId, pti->dwlIterations, dwlSwaps, dwlTicks );
- pti->dwlSwaps = dwlSwaps;
- pti->dwlTicks = dwlTicks;
- SetEvent( pti->hEvtReady );
- }
- return 0;
- }
- void PingPong( DWORD volatile *pdwPingPong, DWORD dwId, DWORDLONG dwlIterations, DWORDLONG &dwlSwaps, DWORDLONG &dwlTicks )
- {
- DWORD dwCmp;
- DWORDLONG dwlTick;
- dwlTick = __rdtsc();
- for( dwlSwaps = 0; dwlIterations; dwlIterations-- )
- {
- if( ((dwCmp = *pdwPingPong) & 1) == dwId )
- if( InterlockedCompareExchange( (LONG *)pdwPingPong, dwCmp + 1, dwCmp ) == dwCmp )
- dwlSwaps++;
- }
- dwlTicks = __rdtsc() - dwlTick;
- }
Advertisement
Add Comment
Please, Sign In to add comment