Guest User

cacheline-transfer

a guest
May 7th, 2017
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.69 KB | None | 0 0
  1. #include <windows.h>
  2. #include <intrin.h>
  3. #include <iostream>
  4.  
  5. using namespace std;
  6.  
  7. struct ThreadInfo
  8. {
  9.     HANDLE              hSemRun;
  10.     bool                fStop;
  11.     HANDLE              hEvtReady;
  12.     DWORD     volatile *pdwPingPong;
  13.     DWORD               dwId;
  14.     DWORDLONG volatile  dwlIterations;
  15.     DWORDLONG volatile  dwlSwaps;
  16.     DWORDLONG volatile  dwlTicks;
  17. };
  18.  
  19. DWORD WINAPI PingPongThread( LPVOID lpvThreadParam );
  20. void PingPong( DWORD volatile *pdwPingPong, DWORD dwId, DWORDLONG dwlIterations, DWORDLONG &dwlSwaps, DWORDLONG &dwlTicks );
  21.  
  22. int main()
  23. {
  24.     DWORDLONG const ITERATIONS = 100000000;
  25.     HANDLE          hSemRun;
  26.     HANDLE          ahEvtReady[2];
  27.     ThreadInfo      ati[2];
  28.     DWORD           dwPingPong;
  29.     HANDLE          ahThreads[2];
  30.     SYSTEM_INFO     si;
  31.     DWORDLONG       dwlAvgTicks;
  32.     DWORDLONG       dwlDummySwaps;
  33.     DWORDLONG       dwlNonSuccessfulXchgTicks;
  34.     double          ticksPerSwap;
  35.  
  36.     SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS );
  37.  
  38.     hSemRun            = CreateSemaphore( NULL, 0, 2, NULL );
  39.     ahEvtReady[0]      = CreateEvent( NULL, FALSE, FALSE, NULL );
  40.     ahEvtReady[1]      = CreateEvent( NULL, FALSE, FALSE, NULL );
  41.     ati[0].hSemRun     = hSemRun;
  42.     ati[1].hSemRun     = hSemRun;
  43.     ati[0].hEvtReady   = ahEvtReady[0];
  44.     ati[1].hEvtReady   = ahEvtReady[1];
  45.     ati[0].fStop       = false;
  46.     ati[1].fStop       = false;
  47.     ati[0].pdwPingPong = &dwPingPong;
  48.     ati[1].pdwPingPong = &dwPingPong;
  49.     ati[0].dwId        = 0;
  50.     ati[1].dwId        = 1;
  51.     ati[0].dwlIterations = 100000000;
  52.     ati[1].dwlIterations = 100000000;
  53.    
  54.     ahThreads[0] = CreateThread( NULL, 0, PingPongThread, &ati[0], 0, NULL );
  55.     ahThreads[1] = CreateThread( NULL, 0, PingPongThread, &ati[1], 0, NULL );
  56.     SetThreadPriority( ahThreads[0], THREAD_PRIORITY_HIGHEST );
  57.     SetThreadPriority( ahThreads[1], THREAD_PRIORITY_HIGHEST );
  58.     SetThreadAffinityMask( ahThreads[0], 1 );
  59.  
  60.     GetSystemInfo( &si );
  61.     for( unsigned processor = 1; processor != (unsigned)si.dwNumberOfProcessors; processor++ )
  62.     {
  63.         SetThreadAffinityMask( ahThreads[1], (DWORD_PTR)1 << processor );
  64.         ReleaseSemaphore( hSemRun, 2, NULL );
  65.         WaitForSingleObject( ahEvtReady[0], INFINITE );
  66.         WaitForSingleObject( ahEvtReady[1], INFINITE );
  67.         //WaitForMultipleObjects( 2, ahEvtReady, TRUE, INFINITE ); // doesn't work; don't know why
  68.  
  69.         dwlAvgTicks = (ati[0].dwlTicks + ati[1].dwlTicks) / 2;
  70.         dwPingPong = 0;
  71.         PingPong( &dwPingPong, 1, ITERATIONS - ati[0].dwlSwaps, dwlDummySwaps, dwlNonSuccessfulXchgTicks );
  72.         ticksPerSwap = (double)(LONGLONG)(dwlAvgTicks - dwlNonSuccessfulXchgTicks) / (LONGLONG)ati[0].dwlSwaps;
  73.         cout << "processor 0 and processor " << processor << ": " << ticksPerSwap << endl;
  74.     }
  75.  
  76.     ati[0].fStop = true;
  77.     ati[1].fStop = true;
  78.     ReleaseSemaphore( hSemRun, 2, NULL );
  79.     WaitForMultipleObjects( 2, ahThreads, TRUE, INFINITE );
  80.    
  81.  
  82.     return 0;
  83. }
  84.  
  85. DWORD WINAPI PingPongThread( LPVOID lpvThreadParam )
  86. {
  87.     ThreadInfo *pti = (ThreadInfo *)lpvThreadParam;
  88.     DWORDLONG   dwlSwaps;
  89.     DWORDLONG   dwlTicks;
  90.  
  91.     for( ; ; )
  92.     {
  93.         WaitForSingleObject( pti->hSemRun, INFINITE );
  94.        
  95.         if( pti->fStop )
  96.             break;
  97.  
  98.         PingPong( pti->pdwPingPong, pti->dwId, pti->dwlIterations, dwlSwaps, dwlTicks );
  99.         pti->dwlSwaps = dwlSwaps;
  100.         pti->dwlTicks = dwlTicks;
  101.         SetEvent( pti->hEvtReady );
  102.     }
  103.  
  104.     return 0;
  105. }
  106.  
  107. void PingPong( DWORD volatile *pdwPingPong, DWORD dwId, DWORDLONG dwlIterations, DWORDLONG &dwlSwaps, DWORDLONG &dwlTicks )
  108. {
  109.     DWORD     dwCmp;
  110.     DWORDLONG dwlTick;
  111.  
  112.     dwlTick = __rdtsc();
  113.     for( dwlSwaps = 0; dwlIterations;  dwlIterations-- )
  114.     {
  115.         if( ((dwCmp = *pdwPingPong) & 1) == dwId )
  116.             if( InterlockedCompareExchange( (LONG *)pdwPingPong, dwCmp + 1, dwCmp ) == dwCmp )
  117.                 dwlSwaps++;
  118.     }
  119.     dwlTicks = __rdtsc() - dwlTick;
  120. }
Advertisement
Add Comment
Please, Sign In to add comment