「たぶん」奇妙な問題に直面しています。実行可能ファイルがあるとしましょう。2 つのコアを搭載したコンピューターで実行すると、プロセスは時間 t1 にわたって実行されます。次に、プロセスの 2 つのインスタンス (同じ実行可能ファイルですが、手動または gnu 並列を使用して起動された別のディレクトリ) を実行すると、各プロセスの実行時間は t1 には近くありませんが、実際には 1.9t1 に近くなります。2 つのコアは物理的なものであることに注意する必要があります (macbook pro mid 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
2 コア マシンの場合、次のデータを取得しました。
時間は秒単位で表されます。たとえば、vector-1 または vector-2 はstd::vector
、それぞれ 1 つまたは 2 つのプロセスを使用して実行した場合の実行時間を意味します。2 つのプロセスについては、2 つの間で最も時間がかかりました。
私が期待すること: 2 つのプロセスの実行時間は、1 つのプロセスの時間とほぼ同じになると思います。ただし、コアの数が十分であっても、複数のインスタンスが実行されている場合、時間は体系的に増加します。前述したように、これはプロセス数が 4 を超える 8 コア マシンでも発生します。
時間の測定方法:time
コマンドを使用して、ユーザー時間を選択しました。システム時間は非常に短いため、1 つまたは 2 つのプロセスが実行されている場合の違いを説明するには不十分です。
gcc 4.6、4.7、4.8、および 4.9 で確認しました。
したがって、私の質問は次のとおりです。なぜこれが起こっているのですか? おそらく、オペレーティングシステムの組み込みと、コアからコアへのプロセスの移行に関連しています。私は本当に知らない。これは私のシミュレーションの実行時間に影響を与えているため、誰かがこれに光を当てることができれば非常に感謝しています。同時に複数のプロセスを実行する必要がありますが、実行時間が増えています。対照的に、別の方法を使用した別のシミュレーション コードは、1 つのプロセスと 2 つのプロセスの両方でほぼ同じ時間で実行されます。ですので、これは自分の手順の問題であるということを、破棄または確認したいと思います。移植可能な方法でプロセッサのアフィニティを設定する方法もわかりません(MacとLinuxの間)。
前もって感謝します