シミュレーション プログラムでサイクルを構成する 2 フェーズ プロセスがあります。多かれ少なかれ、私は次のものを持っています:
struct Coordinates
{
double * x, * y, * z;
uint * kind, count;
double GetDist(const uint p1, const uint p2);
};
struct Polynomial
{
double * A, * B;
uint n1, n2;
uint Flatten(const uint i, const uint j);
double CalcResult(double distSq, uint kind1, uint kind2)
{
uint ij = Flatten(kind1, kind2);
double base = B * distSq;
return A[ij]*(pow(base,n2)-pow(base,n1));
}
};
私の質問は、私のコードを次のように書くかどうかです
struct Model
{
Coordinates c;
Polynomial f;
double DoTest()
{
double result = 0;
uint count = 0;
std::vector<double> distSq;
for (uint i=0; i<c.count; i++)
{
for (uint j=i; j<c.count; j++)
{
result = c.GetDist(i,j);
distSq.push_back(result);
}
}
result = 0;
for (uint i=0; i<c.count; i++)
{
for (uint j=i; j<c.count; j++)
{
result += f.CalcResult(distSq[count], i, j);
count++;
}
}
return result;
}
double DoTest2()
{
double result = 0;
for (uint i=0; i<c.count; i++)
for (uint j=i; j<c.count; j++)
result += f.CalcResult(c.GetDist(i,j), i, j);
return result;
}
}
Test
単一のデータセットでの反復操作を考慮して、x86 チップで並列処理 (ベクトル化された数学や改善されたメモリアクセスなど) を自動的に有効にしますか?
それ以外の場合Test
はガベージ アプローチです。追加のストレージ ( std::vector<double> distSq;
) を使用し、コードの読み取りに関してははるかに長くなります。論理的にはほぼ同じですが、GetDist
f_A
(関数 A) とCalcResult
f_B
(関数 B) を呼び出すと、Test は次のようになります。
f_A f_A f_A ... f_A f_B f_B .... f_B
より短い/より少ないメモリ集約型の機能はどこにありますか
f_A f_B f_A f_B .... f_A f_B
-O#
生成されたベクトル化された数学演算などが原因で、コンパイルされた C コードでいわゆる「固有の並列処理」についての話を聞いたことがありTest
ます。単一のデータセットに対する反復操作?
(それ以外の場合Test2
は、使用するメモリが少ないため、唯一の合理的なアプローチです。)
また、c-style x
、y
、およびz
配列をstd::vector<double>
代替のものに置き換えると、何らかの方法で計算またはメモリアクセスを高速化できる可能性がありますか?
Test
「自分自身をベンチマークする」と答えないでください...コンパイラと「固有の並列処理」に基づいて、理論的な観点からベンチマークを介してアプローチをテストする価値があるかどうかについて、より良い理解を得ようとする理由です。