6

C を使用して行列演算を実行しています。乗算、逆数など、double および int64 データのこれらの行列演算の実行速度を向上させるためのさまざまなコンパイラ最適化フラグを知りたいです。手作業で最適化されたコードを探しているわけではありません。 、コンパイラ フラグを使用してネイティブ コードをより高速化し、これらのフラグについて詳しく知りたいだけです。

これまでに見つけた、マトリックス コードを改善するフラグ。

-O3/O4
-funroll-loops
-ffast-math
4

1 に答える 1

19

まず-ffast-math、次の理由から使用をお勧めしません。

  1. ほとんどの場合 (すべてではないにしても)、このオプションを使用するとパフォーマンスが実際に低下することが証明されています。したがって、「高速計算」は実際にはそれほど高速ではありません。

  2. このオプションは、浮動小数点演算に対する厳密な IEEE 準拠を破り、最終的には予測不可能な性質の計算エラーが蓄積されます。

  3. 異なる環境では異なる結果が得られる可能性があり、その違いはかなりのものになる可能性があります。環境という用語 (この場合) は、ハードウェア、OS、コンパイラの組み合わせを意味します。つまり、予想外の結果が得られる状況の多様性が指数関数的に増加するということです。

  4. もう 1 つの残念な結果は、このオプションでビルドされたライブラリにリンクするプログラムは、正しい (IEEE 準拠の) 浮動小数点演算を期待する可能性があることです。これは彼らの期待が破綻する場所ですが、その理由を理解するのは非常に困難です。

  5. 最後に、この記事をご覧ください。

同じ理由で避けるべきです-Ofast(悪が含まれているため-ffast-math)。エキス:

-Ofast

厳格な基準への準拠を無視します。すべての最適化-Ofastを有効にします。-O3また、すべての標準準拠プログラムに有効ではない最適化も有効にします。-ffast-mathFortran 固有の-fno-protect-parensとがオンになり-fstack-arraysます。

のようなフラグはありません-O4。少なくとも私はそのことを認識しておらず、公式の GCC ドキュメントにはその痕跡はありません。したがって、この点での最大値は で-O3あり、数学を最適化するためだけでなく、一般的なリリース ビルドでも必ず使用する必要があります。

-funroll-loopsこれは、数学ルーチン、特にループのサイズがコンパイル時に推定できる (結果としてコンパイラによって展開される) ベクトル/行列演算を含む場合に非常に適しています。

さらに 2 つのフラグをお勧めします:-march=native-mfpmath=sse. と同様に-O3-march=native数学だけでなく、あらゆるソフトウェアのリリース ビルドに適しています。( x87 モード-mfpmath=sseのスタックの代わりに) 浮動小数点命令で XMM レジスタを使用できるようにします。

さらに、これがベクトル/行列ルーチンの高速化の主な原因であるため、パフォーマンスを向上させるためにコードを変更したくないのは残念です。SIMDSSE Intrinsics、およびVectorizationのおかげで、重い線形代数コードは、それらがない場合よりも桁違いに高速になります。ただし、これらの手法を適切に適用するには、内部構造に関する深い知識と、コードを変更 (実際に書き直す) ためのかなりの時間と労力が必要です。

それにもかかわらず、あなたの場合に適したオプションが1つあります。GCC はで有効にできる自動ベクトル化-ftree-vectorizeを提供しますが、使用しているので不要です-O3(既に含まれているため-ftree-vectorize)。要点は、GCC がどのコードを自動ベクトル化できるかを理解するのを少し手助けする必要があるということです。通常、変更は (必要であれば) マイナーなものですが、慣れておく必要があります。上記のリンクの「ベクトル化可能なループ」セクションを参照してください。

最後に、最も一般的な線形代数ルーチンの非常に効率的な実装を備えた C++ テンプレート ベースのライブラリであるEigenを調べることをお勧めします。これまでに説明したすべての手法を非常に巧妙な方法で利用しています。インターフェイスは純粋にオブジェクト指向で、きちんとしていて、使いやすいです。オブジェクト指向のアプローチは、通常、行列、ベクトル、四元数、回転、フィルターなどの純粋なオブジェクトを操作するため、線形代数に非常に関連しているように見えます。その結果、Eigen を使用してプログラミングする場合、そのような低レベルの概念 (SSE、ベクトル化など) を自分で処理する必要はなく、特定の問題を解決することを楽しむことができます。

于 2013-04-17T20:41:03.097 に答える