我编写了一个使用多线程进行并行计算的程序。我已经验证在我的系统 (OS X) 上它同时最大化了两个内核。我只是将它移植到 Ubuntu,不需要任何修改,因为我在编写代码时就考虑到了该平台。特别是,我在 Amazon EC2 集群计算 4 倍大实例上运行 Canonical HVM Oneiric 图像。这些机器配备 2 个 Intel Xeon X5570 四核 CPU。
不幸的是,我的程序没有在 EC2 机器上完成多线程。运行超过 1 个线程实际上会稍微减慢每个额外线程的计算速度。在我的程序运行时运行top显示,当初始化超过1个线程时,系统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);
...
}
最佳答案
好吧,猜猜看。有一种简单的方法可以将并行代码转换为连续代码。例如:
thread_func:
while (1) {
pthread_mutex_lock(m1);
//do something
pthread_mutex_unlock(m1);
...
pthread_mutex_lock(mN);
pthread_mutex_unlock(mN);
如果你在多个线程中运行这样的代码,你将看不到任何加速,因为使用了互斥锁。代码将连续工作,而不是并行工作。任何时候只有一个线程会工作。
糟糕的是,你不能在你的程序中明确地使用任何互斥量,但仍然会出现这种情况。例如,调用“malloc”可能会导致在“C”运行时的某个地方使用互斥锁,调用“write”可能会导致在 Linux 内核的某个地方使用互斥锁。甚至调用 gettimeofday 也可能导致互斥锁定/解锁(如果告诉 Linux/glibc,它们会导致)。
你可能只有一个互斥锁,但在它下面花费了很多时间,这可能会导致这种行为。
并且由于互斥量可能在内核和 C/C++ 运行时的某处使用,您可以看到不同操作系统的不同行为。
关于c++ pthread 多线程,用于 2 x Intel Xeon X5570,Amazon EC2 HPC ubuntu 实例上的四核 CPU,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8198013/