我目前在4核心Phenom2上使用openmp并行化程序。但是我注意到我的并行化对性能没有任何作用。当然,我认为我错过了一些东西(falsesharing,通过锁序列化,...),但我无法找到这样的事情。此外,从CPU利用率看来,程序似乎只在一个内核上执行。从我发现sched_getcpu()
应该给我的核心线程执行调用目前的计划。所以我写了下面的测试程序:OpenMP线程在相同的CPU核心上执行
#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次测试程序,似乎从CPU利用率(以及系统变得非常没有响应的事实)来看,所有4个内核都可以使用, 。
所以对于我的问题基本上究竟是在这里发生了什么。更重要的是: 我的推论是所有线程都正确地使用相同的内核?如果是这样,那么行为的原因是什么?
继承人您设置了环境变量OMP_NUM_THREADS = 4的常见错误吗? – pyCthon 2012-02-21 01:18:38
@pyCthon:'OMP_NUM_THREADS'似乎没有被设置,但是因为openmp确实创建了4个线程,所以我不认为我需要。 – Grizzly 2012-02-21 01:22:04
奇怪我认为它可能是你的虚拟机的东西,我试过甚至安装了utmpx.h的代码,它似乎在8和16核心机器上工作正常 – pyCthon 2012-02-21 01:58:55