我目前在4核心Phenom2上使用openmp並行化程序。但是我注意到我的並行化對性能沒有任何作用。當然,我認爲我錯過了一些東西(falsesharing,通過鎖序列化,...),但我無法找到這樣的事情。此外,從CPU利用率看來,程序似乎只在一個內核上執行。從我發現sched_getcpu()
應該給我的核心線程執行調用目前的計劃。所以我寫了下面的測試程序:OpenMP線程在相同的CPU核心上執行
#include <iostream>
#include <sstream>
#include <omp.h>
#include <utmpx.h>
#include <random>
int main(){
#pragma omp parallel
{
std::default_random_engine rand;
int num = 0;
#pragma omp for
for(size_t i = 0; i < 1000000000; ++i) num += rand();
auto cpu = sched_getcpu();
std::ostringstream os;
os<<"\nThread "<<omp_get_thread_num()<<" on cpu "<<sched_getcpu()<<std::endl;
std::cout<<os.str()<<std::flush;
std::cout<<num;
}
}
在我的機器這讓下面的輸出(隨機數會有所不同,當然):
Thread 2 on cpu 0 num 127392776
Thread 0 on cpu 0 num 1980891664
Thread 3 on cpu 0 num 431821313
Thread 1 on cpu 0 num -1976497224
從這個我認爲所有的線程上執行相同的核心(具有ID 0的核心)。爲了更確定我還嘗試了從this answer的方法。結果在哪裏相同。另外使用#pragma omp parallel num_threads(1)
並沒有使執行速度變慢(實際上稍微快一點),這使得所有線程都使用相同cpu的理論具有可信性,但是cpu始終顯示爲0
這一事實讓我有點懷疑。另外我檢查了GOMP_CPU_AFFINITY
最初沒有設置,所以我嘗試將它設置爲0 1 2 3
,它應該將每個線程綁定到我瞭解的不同內核。但是這並沒有什麼區別。
由於在windows系統上開發,我在virtualbox中使用linux進行開發。所以我儘管可能虛擬系統無法訪問所有內核。然而,檢查virtualbox的設置表明,虛擬機應該獲得所有4個內核,並同時執行4次測試程序,似乎從CPU利用率(以及系統變得非常沒有響應的事實)來看,所有4個內核都可以使用, 。
所以對於我的問題基本上究竟是在這裏發生了什麼。更重要的是: 我的推論是所有線程都正確地使用相同的內核?如果是這樣,那麼行爲的原因是什麼?
繼承人您設置了環境變量OMP_NUM_THREADS = 4的常見錯誤嗎? – pyCthon 2012-02-21 01:18:38
@pyCthon:'OMP_NUM_THREADS'似乎沒有被設置,但是因爲openmp確實創建了4個線程,所以我不認爲我需要。 – Grizzly 2012-02-21 01:22:04
奇怪我認爲它可能是你的虛擬機的東西,我試過甚至安裝了utmpx.h的代碼,它似乎在8和16核心機器上工作正常 – pyCthon 2012-02-21 01:58:55