14

私は vampire ( http://github.com/richard-evans/vampire ) と呼ばれるオープン ソースの科学的コードの作成者であり、計算集約型であることは、コード パフォーマンスの改善により、実行できる研究の量が大幅に増加することを意味します。このコードの通常の実行時間は数百コア時間になる可能性があるため、コードのパフォーマンス クリティカル セクションを改善する方法を常に探しています。ただし、実行時間の約 40% を占める、比較的無害に見える次のコードに少し行き詰まりました。

for (int atom = start_index; atom < end_index; atom++){
    register double Hx = 0.0;
    register double Hy = 0.0;
    register double Hz = 0.0;
    const int start = atoms::neighbour_list_start_index[atom];
    const int end = atoms::neighbour_list_end_index[atom] + 1;
    for (int nn = start; nn < end; nn++){
        const int natom = atoms::neighbour_list_array[nn];
        const double Jij = atoms::i_exchange_list[atoms::neighbour_interaction_type_array[nn]].Jij;
        Hx -= Jij * atoms::x_spin_array[natom];
        Hy -= Jij * atoms::y_spin_array[natom];
        Hz -= Jij * atoms::z_spin_array[natom];
    }
    atoms::x_total_spin_field_array[atom] += Hx;
    atoms::y_total_spin_field_array[atom] += Hy;
    atoms::z_total_spin_field_array[atom] += Hz;
}

このコードの関数と変数の高レベルの概要は次のとおりです。atoms::x_spin_array「スピン'。これらの各スピンは他のいくつかのスピンと相互作用し、すべての相互作用は 1D 近傍リスト ( atoms::neighbour_list_array) として保存されます。各原子に関連する相互作用のリストはlistarray、2 つの別個の配列内の隣接する原子の開始インデックスと終了インデックスによって決定されます。計算の最後に、各原子スピンは相互作用のベクトル和である実効場を持ちます。

少量のコードとそれが占めるランタイムのかなりの部分を考えると、私は最善を尽くしましたが、これをさらに最適化する方法があるに違いないと感じていますが、コンピューター科学者ではなく物理学者として、何かが足りないのでしょうか?

4

3 に答える 3

6

連続するデータに対する乗算、減算、および加算の一定のストリームがあります。これは SSE の理想的な使い方のようです。メモリ帯域幅が制限されている場合は、代わりに OpenCL/CUDA を使用してください。

すべての低レベルの命令に慣れていない場合は、このライブラリを使用してみてください。

その内部ループは、大幅に再構築される可能性があり、速度向上につながる可能性があります。

于 2013-07-23T09:50:50.447 に答える
2

xyzコンポーネントが実際にリンクされたリストである場合x[i]、を実行するy[i]z[i]、リストが複数回走査され、(n^2)/2反復が行われます。ベクトルを使用すると、これがO(1)操作になります。

メモリ キャッシュの目的で 3 つの座標が分割されているとのことですが、メモリ内の 3 つの異なる領域にアクセスしているため、これはレベル 1 とレベル 2 のキャッシュの局所性に影響します。リンクされたリストは、キャッシュの局所性にも影響を与えています。

次のようなものを使用します。

struct vector3d {
    double x;
    double y;
    double z;
};

std::vector<vector3d> spin;
std::vector<vector3d> total_spin;

これにより、x、y、z の値がメモリ内で隣接し、スピンがメモリの線形ブロックを占有するため、キャッシュの局所性が向上するはずです。

于 2013-07-23T10:34:21.153 に答える
0

次の提案は、完全ではないにしても、コードを少し最適化するのに役立つと思います。

  1. 可能な限り割り当てよりも初期化を使用する
  2. 速度を向上させるために、ポストよりも事前インクリメントを優先します(信じてください、それは変更を行います)

それを除けば、コードは問題ないと思います。各 DS には長所と短所があります。

ハッピーコーディング!

于 2013-07-23T09:04:28.180 に答える