我目前正在使用openmp在4核phenom2上并行化程序。但是我注意到我的并行化对性能没有任何作用。当然我以为我错过了一些东西(falsesharing,通过锁定序列化......),但是我无法找到类似的东西。此外,从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利用率(以及系统变得非常无响应的事实) 。
所以我的问题基本上就是这里究竟发生了什么。更重要的是: 我的推论是否所有线程都正确使用相同的核心?如果是,那可能是什么原因?
答案 0 :(得分:6)
经过一些实验,我发现问题在于我是从eclipse IDE中启动我的程序,这似乎设置了仅使用一个核心的亲和力。我认为从IDE外部启动时遇到了同样的问题,但重复测试表明程序运行正常,从终端启动而不是从ide内部启动。
答案 1 :(得分:2)
我在Linux上使用g ++ 4.6编译了你的程序
g++ --std=c++0x -fopenmp test.cc -o test
输出结果不出所料:
Thread 2 on cpu 2
Thread 3 on cpu 1
910270973
Thread 1 on cpu 3
910270973
Thread 0 on cpu 0
910270973910270973
启动4个线程的事实(如果你没有以任何方式设置线程数,例如使用OMP_NUM_THREADS)应该意味着程序能够看到4个可用的CPU。我无法猜测为什么它没有使用它们但我怀疑你的硬件/软件设置,某些环境变量或编译器选项中存在问题。
答案 2 :(得分:0)
您应该使用#pragma omp parallel for
是的,你是不对的,不需要OMP_NUM_THREADS。 omp_set_num_threads(4);
也应该做得很好。
答案 3 :(得分:0)
如果您在Windows上运行,请尝试以下方法:
c:\ windows \ system32 \ cmd.exe / C start / affinity F path \ to \ your \ program.exe
/ affinity 1使用CPU0
/ affinity 2使用CPU1
/ affinity 3使用CPU0和CPU1
/ affinity 4使用CPU2
/ affinity F使用全部4个核心
将数字转换为十六进制,并查看右边的位,这些位是要使用的核心。
您可以使用任务管理器验证其运行时的亲和力。