2017-12-27 89 views
1

私はいくつかのコードをより高速に実行しようとしています。浮動小数点コード用のg ++​​最適化スイッチ

  • パラメータ(定数、二重、INT)入力値の
  • アレイ(定数、二重)

出力される

    :入力として取って - それは点集中コードを浮遊しています
  • 値の配列(double)
  • ヤコビ行列

現在、私は

g++-7 (Ubuntu 7.2.0-1ubuntu1~16.04) 7.2.0 

、次のコマンドライン使用しています:G ++コンパイラは、過去に、より良いコードを生成する私の記憶から

g++-7 -S -fPIC -O3 -DNDEBUG -funroll-loops -march=native -ffast-math \ 
-I $BOOST_DIR tmp.cpp -std=c++17 \ 
-D__forceinline='__attribute__((always_inline))' \ 
-frecord-gcc-switches -Wno-attributes 

- ともずっとそのようなコードを噛んでましたがより長いです。私はさまざまなオプションで試してみましたが、唯一

--param max-gcse-memory=1 

は、この引数を使用するか使用しないかの間に効果があるようです。パラメータ値の変更は無視されます。

より良いコードのための私の基準はコードでVMOV/mov命令の量は、[SP] D命令をvmulと比較されます。より良いコードには、[v] mov命令の数を少なくする必要があります。

私は10766 [V]のmov命令は、このパラメータなしで11325に比べて取得しています

--param max-gcse-memory=1 

を使用。 これは、1000回のvmulpdと1900回のvmulsdとの比較です。両方の試行の間で、数値はほぼ一定です。

再び - 私は、コンパイル時間を気にしません。私はよりよいコードを取得したいと思います。過去(2010年)に覚えていることから、コンパイル時間がずっと長くなるなど、より良いコードが得られました。

+0

古いバージョンをインストールして比較することはできませんか?また、ネイティブアーキテクチャは変更されていませんか? – visibleman

+2

このレベルでは、mov vs mulを計算することは本当に粗雑な経験則です。実行時間を代表データで比較する必要があります。 –

答えて

1

SIMD命令は、多くの場合、整列されたデータを必要とします。不十分なデータの整列を防ぐために、GCCが多くのコードを生成しているようです。

コードを変更することができる場合は、aligned属性、またはさらに優れたOpenMP SIMDプラグマを使用すると効果があるように思えます。機能の可視性を制限することができますよう

プログラムが構成されている方法に応じて、LTO(-flto)は、大きな違いを生むことができ(すなわち、-fvisibility =非表示)。

は基本的に、あなたはそれが適切にSIMD命令のために整列物事を取得するために余分なコードの多くをドロップすることができますので、多くの部屋ができるだけ動作するようオプティマイザを与えたいです。

あなたはまた、より多くのISA拡張機能を有効にすることを検討することをお勧めします... AVXは、あなたが命令で二倍の作業を行うことができることを意味しており、256ビットのベクトルをサポートし、あなたのCPUがそれをサポートする良いチャンスがあります。実行可能ファイルを出荷して他のコンピュータで実行する場合は、複数のISA拡張に最適化されたコードを簡単に生成するためにtarget_clones属性を使用することを検討してください。

+0

OPは '-march = native'を使っています。これはあなたのCPUがサポートしているすべてのものを有効にし、skylakeのようなものなら' -mtune = skylake'を設定します。しかし、 'LTO'は良い提案です。OpenMPは、gccに重要なループを自動ベクトル化させることができない場合(例えば' __restrictの使用が十分でない、OpenMP 。 –

+0

ああ、そうです-march = nativeを見逃しましたOpenMPでは、ここで私が話していた文脈である整列を指定することもできます.GCCがコードをベクトル化しているように、 – nemequ

+0

はい、gccのバニラ自動ベクトル化戦略は、完全に展開されています(これは完全に展開されています)。スカラーイントロ/アウトロスは、インナーループ内のポインタの1つのアライメント境界に到達します(しかし、インナーループではアンローリングはありません)。ワイドベクトル(特に狭い整数型)では膨大なコードになります。 https://stackoverflow.coを参照してください。 m/questions/38552116 /コンパイラの出力を調べるためのヒントについては、gcc-clang-assembly-outputのhow-to-remove-noiseを参照してください:TL:DR:http://gcc.godbolt.org/に載せてください。 –