6

numpy で書かれたコードがいくつかあり、パフォーマンスを向上させるために Fortran に移植することを検討しています。

私が何度か行う操作の 1 つは、2 つの配列の要素ごとの積を合計することです。

sum(A*B)

融合された乗加算命令がこれに役立つようです。現在のプロセッサはこれらの命令をサポートしていないため、まだテストできません。ただし、FMA3 (Intel Haswell プロセッサ) をサポートする新しいプロセッサにアップグレードする可能性があります。

「-march=native」(または相当する ifort) を使用してプログラムをコンパイルするだけで、コンパイラ (gfortran または ifort) が SIMD 命令を賢く使用してそのコードを最適化するのに十分かどうか、誰にもわかりますか?コンパイラやコードを赤ちゃんにする必要がありますか?

4

3 に答える 3

3

SIMD を搭載したマシンで使用する場合-march=native、コンパイラは SIMD 命令を生成する必要がありますが-xHost、ifort の代わりにフラグを常に使用してきました。

しかし、彼らにそれを「賢く」させる方法がよくわかりません。私の感覚では、-O3ifort と gfortran はどちらもベクトル化に対して過度に積極的である傾向があります (つまり、SIMD 機能を必要以上に頻繁に使用します)。最も効率的なコードを得るために、ベクトル化をオフにする必要があることがよくあります。もちろん、これはあなたに当てはまる場合とそうでない場合があります。

通常、このタスク用に最適化されたベクター ライブラリを使用することをお勧めします。vdmulこれを行うには、MKL またはgsl_vector_mulGSL で 使用できます。

を使用-march=NEWARCHすると、アーキテクチャ NEWARCH 用に調整されたコードになりますが、以前のアーキテクチャでは実行できません。-mtune=NEWARCHNEWARCH が新しいプロセッサのアーキテクチャであるフラグを使用できます。これにより、新しいアーキテクチャ用に調整されたコードが生成されますが、古いアーキテクチャでも実行可能です。あなたはまだ新しいマシンを持っていないので、-mtuneおそらく現時点で必要なものです.

ifort では、ベクトル化レポート フラグを使用して、プログラムのどの部分がベクトル化されたかを示すことができます。たとえば、ifortフラグ-vec-report=1はコンパイル中にそのような情報を提供します。gfortran にも同等のフラグがあると確信しています。

于 2014-01-11T17:53:14.427 に答える
2

sum(a*b)廃止されたよりも優れたベクトル化を提供する gfortran バージョンdot_product(a,b)。表示するコードは、シリアル AVX2 fma 命令を使用しています。

間接的なインデックス付けやその他の複雑な処理 (単純なループ自体)のない の実装ではdot_product、fma は、simd 並列乗算と加算命令の組み合わせよりも遅くなる可能性があります。dot_product に並列 simd fma を使用する gfortran は、より複雑な場合に非常に効果的です。

-O2 -ftree-vectorize -ffast-math -march=native or -O3 -ffast-math -march=nativeこれをベクトル化するには、(適切なベクトル長と同様に)いずれかが必要であり、gfortran は OpenMP 並列領域内でベクトル化に失敗する可能性があります。

gfortran 4.9 では、オプション -ftree-vectorizer-verbose が削除されたようです。-fdump-tree-vect は、ベクトル化パスの詳細を .vect ファイルに書き込み、主要な gcc バージョンごとに異なる名前を選択します。

于 2014-01-28T17:37:10.547 に答える