C++ 为什么两个内核上的两个实例的运行时间大于一个实例的运行时间?
我正面临一个“可能”的奇怪问题。假设我有一个可执行文件。当我在一台有两个内核的计算机上运行它时,这个过程会运行一段时间t1。然后,如果我运行两个进程实例(相同的可执行文件,但在不同的目录上,手动启动或使用gnu并行启动),每个进程的运行时间不接近t1,但实际上更大,有时接近1.9t1。我必须指出,这两个核心是物理的(MacBookPro 2009年年中,Mountain Lion)。我还在一台8核的linux机器上测试了这种行为。如果我运行1、2、3和4个实例,每个实例的运行时间大约为t1。但是,在5个、6个、7个和8个实例之后,每个实例的运行时间越来越大于t1 我在运行模拟时检测到这种行为。我能够将测试用例简化为下面介绍的简单测试。我想在几个编译级别上检查C++ 为什么两个内核上的两个实例的运行时间大于一个实例的运行时间?,c++,c,C++,C,我正面临一个“可能”的奇怪问题。假设我有一个可执行文件。当我在一台有两个内核的计算机上运行它时,这个过程会运行一段时间t1。然后,如果我运行两个进程实例(相同的可执行文件,但在不同的目录上,手动启动或使用gnu并行启动),每个进程的运行时间不接近t1,但实际上更大,有时接近1.9t1。我必须指出,这两个核心是物理的(MacBookPro 2009年年中,Mountain Lion)。我还在一台8核的linux机器上测试了这种行为。如果我运行1、2、3和4个实例,每个实例的运行时间大约为t1。但是
std::vector
,std::array
,静态和动态数组。测试代码如下所示:
#include <iostream>
#include <vector>
#include <array>
#include <cstdlib>
struct Particle {
private:
int nc;
public:
void reset(void) { nc = 0; };
void set(const int & val) { nc = val; };
};
#define N 10000 // number of particles
#define M 200000 // number of steps
#define STDVECTOR 0
#define STDARRAY 0
#define ARRAY 1
#define DYNARRAY 0
int main (void)
{
#if STDVECTOR
std::vector<Particle> particles(N);
#elif STDARRAY
std::array<Particle, N> particles;
#elif ARRAY
Particle particles[N];
#elif DYNARRAY
Particle *particles; particles = new Particle [N];
#endif
int jj = 0;
for (int ii = 0; ii < M; ++ii) {
//for (auto & body : particles) body.reset();
for (int idx = 0; idx < N; ++idx) particles[idx].reset();
jj = ii;
}
particles[0].set(jj*drand48());
return 0;
}
#包括
#包括
#包括
#包括
结构粒子{
私人:
int nc;
公众:
无效重置(无效){nc=0;};
空集(const int&val){nc=val;};
};
#定义N 10000//粒子数
#定义M 200000//步数
#定义STDVECTOR 0
#定义标准数组0
#定义数组1
#定义DYNARRAY 0
内部主(空)
{
#中频机顶盒
std::矢量粒子(N);
#埃利夫·斯达雷
阵列粒子;
#elif阵列
粒子[N];
#艾利夫·戴纳雷
粒子*粒子;粒子=新粒子[N];
#恩迪夫
int jj=0;
对于(int ii=0;ii
编译测试如下所示
用于0 1 2 3中的a;执行printf“\n\nOPT=$a\n\n”;g++-4.8-O${a}-O tmp.x tmp.cpp;cp tmp.x simul01/;cp tmp.x simul02/;时间模拟01/tmp.x;并行'time{}/tmp.x'::simul01 simul02;完成
对于双核机器,我获得了以下数据:
其中时间以秒为单位,例如,vector-1或vector-2表示分别使用std::vector
和运行一个或两个进程时的运行时间。对于这两个过程,我用了两个过程之间最长的时间
我期望:我期望两个进程的运行时间与单个进程的运行时间相似。但是,当有多个实例在运行时,即使内核的数量足够多,时间也会系统性地增加。正如我所说,当进程数大于4时,8核机器也会发生这种情况
如何测量时间:我使用time
命令,选择用户时间。系统时间太少,不足以解释一个或两个进程运行时的差异
我已经检查了GCC4.6、4.7、4.8和4.9
因此,我的问题是:为什么会发生这种情况?可能与操作系统的某些固有特性以及进程从核心到核心的迁移有关。我真的不知道。我非常感谢有人能解释这一点,因为这会影响我模拟的运行时间。我需要同时运行几个进程,但运行时间正在增加。相反,对于一个进程和两个进程,使用不同方法的另一个模拟代码的运行时间大致相同。因此,我想放弃或确保这是我自己的程序的问题。我也不知道如何以可移植的方式(在mac和linux之间)设置处理器相关性
提前感谢您的编译器CPU可能会自动执行代码线程。因此,您将通过1个实例获得最大性能。。。因此,运行2个实例将花费大约两倍的时间。请记住,在2个内核上,还有其他任务与应用程序一起运行(内核线程、后台进程等)。引入另一个CPU密集型任务意味着可能会有线程跨内核迁移,本质上它们是在争夺资源。对于具有更多内核的Linux场景也是如此。一旦达到某个限制,您将与系统上的其他进程竞争,无论是您生成的进程还是后台进程和内核线程等……可能有很多事情:
您可以通过使用分析工具(如
oprofile
或perf
)来判断这些选项中的哪一个(或其他),并检查机器上的各种性能计数器,比较1进程与2进程场景 它可能使用1个物理内核和hyper-thre