我正面临着一个“也许”的奇怪问题。假设我有一个可执行文件。当我在一台有两个核心的计算机上运行它时,该进程在time t1上运行。然后,如果我运行该进程的两个实例(相同的可执行文件,但位于不同的目录,手动启动或使用gnu并行启动),每个进程的运行时间并不接近t1,但实际上更长,有时接近1.9t1。我必须指出的是,这两个内核都是物理的(macbook pro 2009年中,Mountain Lion)。我还在一台具有8个内核的linux机器上测试了这种行为。如果我运行1、2、3和4个实例,每个实例的运行时间大约是t1。但是,在5、6、7和8个实例之后,每个实例的运行时间逐渐大于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;
}
编译测试是这样完成的:
for a in 0 1 2 3; do printf "\n\nOPT=$a\n\n"; g++-4.8 -O${a} -o tmp.x tmp.cpp; cp tmp.x simul01/ ; cp tmp.x simul02/; time simul01/tmp.x ; parallel 'time {}/tmp.x' ::: simul01 simul02 ; done
对于双核机器,我获得了以下数据:
其中时间以秒为单位,例如,向量-1或向量-2分别表示使用std::vector
和运行一个或两个进程时的运行时间。对于这两个过程,我花费了两个过程中最长的时间。
我期望的:我期望两个进程的运行时间与单个进程的运行时间相似。但是,当多个实例正在运行时,即使内核数量足够,时间也会有系统地增加。正如我所说的,对于八核机器,当进程数大于4时,也会发生这种情况。
我如何测量时间:我使用time
命令,并选择用户时间。系统时间太小,不足以解释一个或两个进程正在运行时的差异。
我已经和gcc核实了4.6,4.7,4.8和4.9。
因此,我的问题是:为什么会发生这种情况?可能与操作系统的某些固有特性以及进程从一个内核迁移到另一个内核有关。我真的不知道。如果有人能对此有所了解,我将非常感激,因为这会影响我的模拟运行时间。我需要同时运行多个进程,但是运行时间越来越长。相比之下,对于一个和两个进程,另一个具有不同方法的模拟代码几乎在相同的时间内运行。因此,我希望丢弃或确保这是我自己的过程的问题。我也不知道如何以可移植的方式设置处理器亲和性(在mac和linux之间)。
提前感谢
发布于 2013-09-13 09:06:33
请记住,与应用程序一起运行的还有其他任务(内核线程、后台进程等)。在两个核心上,引入另一个CPU密集型任务意味着可能存在跨核心的线程迁移,本质上它们是在争夺资源。对于内核更多的Linux场景也是如此。一旦达到某个限制,您将与系统上的其他进程竞争,无论是您衍生的进程,还是后台进程和内核线程,等等。
发布于 2013-09-13 09:08:06
可能有很多东西:
上面的列表远远不是一个完整的可能性列表,而只是一些更常见的可能性。
您可以通过使用评测工具(如oprofile
或perf
)来判断这些选项中的哪一个(或其他一些),并检查机器上的各种性能计数器,将1进程方案与2进程方案进行比较。
https://stackoverflow.com/questions/18776518
复制相似问题