c++ pthread 多线程,用于 2 x Intel Xeon X5570,Amazon EC2 HPC ubuntu 实例上的四核 CPU

标签 c++ multithreading ubuntu amazon-ec2 pthreads

我编写了一个使用多线程进行并行计算的程序。我已经验证在我的系统 (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/

相关文章:

c++ - 如何将字符串混淆成 C++ 二进制文件?

java - 从子类的线程调用 JTextArea.append()

python - 如何启动连接到您正在监听的套接字的进程?

ubuntu - 为什么我无法安装 phantomjs(错误 : EACCES: permission denied)?

mysql - 使用 HAproxy 拆分 mysql 集群的读/写

ubuntu - ROS:如何使用 rqt_plot 显示/geometry_msgs/PoseWithCovarianceMessage 的字段?

C++ 中类似 Python 的迭代器习语

c++ - pthreads 中的内存模型规范

c++ - std::get_time - 如何检查解析错误

multithreading - JavaFx ProgressBar 不更新