我寫了一個程序,採用多線程進行並行計算。我已經證實,在我的系統(OS X)上它同時最大化了兩個內核。我只是將它移植到Ubuntu上,不需要任何修改,因爲我在考慮該平臺的情況下對其進行了編碼。特別是,我在Amazon EC2上運行Canonical HVM Oneiric映像,這是一個集羣計算4x大型實例。這些機器配備2個Intel Xeon X5570四核CPU。C++ pthread多線程處理2個Intel Xeon X5570,四核CPU上Amazan EC2 HPC ubuntu實例
不幸的是,我的程序沒有在EC2機器上完成多線程。運行多個線程實際上會減慢每個附加線程的運算速度。在我的程序運行時運行頂部顯示,當多於一個線程被初始化時,CPU消耗的系統%大致與線程數成比例。只有1個線程,%sy是〜0.1。無論哪種情況,用戶%都不會超過〜9%。
下面是我的代碼
const int NUM_THREADS = N; //where changing N is how I set the # of threads
void Threading::Setup_Threading()
{
sem_unlink("producer_gate");
sem_unlink("consumer_gate");
producer_gate = sem_open("producer_gate", O_CREAT, 0700, 0);
consumer_gate = sem_open("consumer_gate", O_CREAT, 0700, 0);
completed = 0;
queued = 0;
pthread_attr_init (&attr);
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
}
void Threading::Init_Threads(vector <NetClass> * p_Pop)
{
thread_list.assign(NUM_THREADS, pthread_t());
for(int q=0; q<NUM_THREADS; q++)
pthread_create(&thread_list[q], &attr, Consumer, (void*) p_Pop);
}
void* Consumer(void* argument)
{
std::vector <NetClass>* p_v_Pop = (std::vector <NetClass>*) argument ;
while(1)
{
sem_wait(consumer_gate);
pthread_mutex_lock (&access_queued);
int index = queued;
queued--;
pthread_mutex_unlock (&access_queued);
Run_Gen( (*p_v_Pop)[index-1]);
completed--;
if(!completed)
sem_post(producer_gate);
}
}
main()
{
...
t1 = time(NULL);
threads.Init_Threads(p_Pop_m);
for(int w = 0; w < MONTC_NUM_TRIALS ; w++)
{
queued = MONTC_POP;
completed = MONTC_POP;
for(int q = MONTC_POP-1 ; q > -1; q--)
sem_post(consumer_gate);
sem_wait(producer_gate);
}
threads.Close_Threads();
t2 = time(NULL);
cout << difftime(t2, t1);
...
}
也許會發生這種情況,因爲EC2核心是虛擬核心而不是真正的金屬固體核心 – fabrizioM
您可以提供最少的來源,可以編譯? – fghj
@ user1034749自從您發佈此嘗試隔離問題代碼以來,我花了數小時,並且我仍然有一種方法,直到我完全縮小它的範圍。我確定的是,它取決於'Consumer()'中調用的'工作'。我用一個虛擬函數替換了'Run_Gen',它只是循環浪費時間,然後線程按設計工作。 'Run_Gen'發生了很多事情(因此困難),但沒有一個是非常特殊的,只是向量和算術。對可能發生的事情有任何想法,至少在一般情況下。 –