N
簡単にするために、各行の行列のベクトルがあると仮定しM
ます。STLstd::accumulate
を使用して、すべての行列の合計を計算しています。2 つの行列を (参照により) 受け取り、それらの合計を (参照により) 返すバイナリ ファンクターを渡します。完全な開示: libstdc++ 並列モードを使用しています。ファンクター内では、行を個別にループして合計を計算します。
各マトリックスは大きすぎてキャッシュに収まりませんが、行は非常にうまく収まります。そのため、ループの順序を変更して、外側のループがM
行にインデックスを付け、内側のループがN
行列にインデックスを付けるようにすることをお勧めします。ファンクターをインラインで定義することに加えて、このようなクロス関数境界ループの並べ替えを促進するために他にできることはありますか? もちろん、コードを再構築することもできますが、理想的には、STL アルゴリズムを使用できる単純な構造を維持したいと考えています。gcc 固有のものがあれば、それも気にしません。
私は実際に行列を扱っているわけではありません。これは単なる例ですが、同じ問題構造が適用されます。主な問題はパフォーマンスの問題です。実際のシナリオを説明するのは面倒ですが、核となる問題は次のとおりです。STL のアキュムレートは、次のオブジェクトに移動する前に 2 つのオブジェクトの追加を完了しようとするため、ネストされたループ間の順序付けを伴います。これはキャッシュ フレンドリーではありません。1 つのオブジェクトは大きすぎてキャッシュに保持できませんが、一部は保持できます。そのため、(すべてのオブジェクトに対して) 一度に 1 つの「部分」の「加算」を計算すると、実行を高速化できます。ループを手動で並べ替えると、FLOPS が大幅に改善されます。しかし、可能な限り STL レベルでコーディングできるように、コンパイラーに並べ替えを実行してもらいたいと考えています。だから私はこれを行うためのトリックを探しています。