c++ - 在同一个 cpu 内核上执行的 OpenMP 线程

标签 c++ linux openmp virtualbox

我目前正在 4 核 phenom2 上使用 openmp 并行化程序。但是我注意到我的并行化对性能没有任何影响。自然地,我假设我错过了一些东西(虚假共享,通过锁序列化,...),但是我找不到类似的东西。此外,从 CPU 利用率来看,程序似乎只在一个内核上执行。根据我的发现,sched_getcpu() 应该给我执行调用的线程当前安排的核心 ID。所以我写了下面的测试程序:

#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,这应该将每个线程绑定(bind)到与我理解的不同的核心。然而,这并没有什么不同。

由于在windows系统上开发,所以我在virtualbox中使用linux进行开发。所以我认为虚拟系统可能无法访问所有内核。然而,检查 virtualbox 的设置显示虚拟机应该获得所有 4 个内核,同时执行我的测试程序 4 次似乎使用了所有 4 个内核,从 cpu 利用率来看(以及系统变得非常无响应的事实) .

所以我的问题基本上就是这里到底发生了什么。更重要的是: 我的推论是所有线程都正确使用同一个核心吗?如果是,那么这种行为的原因可能是什么?

最佳答案

经过一些实验后,我发现问题出在我是从 eclipse IDE 内部启动我的程序,这似乎将 affinity 设置为仅使用一个内核。我以为我从 IDE 外部启动时遇到了同样的问题,但重复测试表明,当从终端启动而不是从 IDE 内部启动时,程序工作正常。

关于c++ - 在同一个 cpu 内核上执行的 OpenMP 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9370754/

相关文章:

c++ - openmp两个连续循环,归约子句问题

C、OpenMP : How can I make this parallisation of a triple loop better?

c++ - 如何获得 QHBoxLayout 固定高度?

c++ - 如何解决 RapidXML 字符串所有权问题?

Linux 控制台更改,打印 OK,读取 NOK

python - letsencrypt 失败,ImportError : No module named interface

c++ - 为什么使用openmp时会间歇性出现 “fatal error C1001”错误?

c++ - std::function 的模板参数(签名)不是其类型的一部分吗?

c++ - 抽象工厂查询

linux - 使用SIGALRM中断open()