2014-06-11 155 views
2

我有這樣的代碼:多線程 - 線程每個核心

#define threadsNum 4 

DWORD WINAPI func(LPVOID vpParam) 
{ 
    long long sum = 0; 

    for(int i = 0; i < 400000/threadsNum; i++) 
    { 
     for(int j = 0; j < 160000/threadsNum; j++) 
     { 
      sum = sum > 1000 ? 0 : sum + 1; 
     } 

    } 

    return 1; 
} 


int main() 
{ 
    clock_t timer = clock(); 

    int CPUs = 4; 
    DWORD_PTR threadCore = 1; 
    DWORD_PTR threadID = 0; 
    int addNum = 0; 

    void* *threads = new void*[threadsNum]; 

    for (int i = 0; i < threadsNum; i++) 
    { 
     threadCore = 1 << addNum; 
     addNum++; 
     if (addNum == 4) 
      addNum = 0; 

     threads[i] = CreateThread(0, 0, func, NULL , 0, &threadID); 
     SetThreadAffinityMask(threads[i], threadCore); 
    } 

    if (WaitForMultipleObjects(threadsNum, threads, true, INFINITE) == WAIT_FAILED) 
     FatalAppExitA(NULL, "FAIL"); 


    cout<<clock() - timer<<endl; 

    getchar(); 


    return 1; 
} 

我有4個內核上的我的電腦。隨着threadsNum數量的增加,時間越來越短。當threadsNum等於4時,輸出是22325,當它是8時,輸出是11549.爲什麼?每個核心都做同樣的工作。對於threadsNum = 8每個核心都有2個線程,當threadsNum = 4時它們一起執行相同的工作。那麼爲什麼它更快?

+1

線程可能被搶佔,並可能正在做一些IO ... – Theolodis

回答

5

如果8個線程在4核CPU上比4快得多,那麼您可能有一個帶超線程的Intel CPU,每個CPU運行兩個硬件線程。它通常不像實際的8核CPU那麼快,因爲每個核心上的兩個線程共享一些硬件資源,但對於這樣的簡單線程負載,您可能會接近2倍的提高(似乎是這樣做)。

+0

op可以嘗試繪製線程數從1到64的執行時間 - 這將暴露線程模式從CPU。現代cpu無論如何都有循環重組和分支預測,這些都有助於和隱藏這些綜合基準的性能。 –

1

有2個主要罪魁禍首,但你將不得不基準更多,以找出每個貢獻多少。

  1. 線程被IO阻塞的IO綁定任務。在這種情況下,「IO」將是內存訪問。一個線程可以添加,而另一個線程被阻塞等待讀取或寫入。
  2. Hyperthreading。在現代處理器中,每個核心幾乎可以表現得像兩個核心。