【发布时间】:2023-04-02 15:52:01
【问题描述】:
我目前在 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,这应该将每个线程绑定到我理解的不同核心。然而,这并没有什么不同。
由于是在windows系统上开发,所以我在virtualbox中使用linux进行开发。所以我认为虚拟系统可能无法访问所有内核。但是检查virtualbox的设置显示虚拟机应该获得所有4个核心并同时执行我的测试程序4次似乎使用所有4个核心从CPU利用率判断(以及系统变得非常无响应的事实) .
所以我的问题基本上是这里到底发生了什么。更重要的是: 我是否推断所有线程都正确使用相同的内核?如果是,那么这种行为的原因可能是什么?
【问题讨论】:
-
这是一个常见错误,您是否设置了环境变量 OMP_NUM_THREADS =4?
-
@pyCthon:
OMP_NUM_THREADS似乎没有设置,但是由于 openmp 确实创建了 4 个线程,我认为我不需要。 -
很奇怪,我认为这可能与您的虚拟机有关,我尝试了相同的代码,甚至安装了 utmpx.h,它似乎在 8 核和 16 核机器上运行良好
-
我在某处读到虚拟机(来宾操作系统)在您的主机操作系统内作为单个进程运行。这可能是您所看到的行为的原因吗?
-
在我使用 Scientific Linux 6 的 2 CPU x86-64 服务器上也发生了同样的情况。看不到 IDE 或虚拟机。
标签: c++ linux openmp virtualbox