PGI 一般的に使用するオプション fast fastsse
一般にコンパイルを使用するときの最適化オプションを説明しています。PGI コンパイラを使って実行モジュールが、最速になるように最適化する一般的なオプションの説明です。 (PGI 16.1 以降、Windows 版の C++ コンパイラの提供は廃止されました。)
2016年2月6日更新 Copyright © 株式会社ソフテック
PGI の F77, F2003, C, C++ のコンパイラを使用する際に、性能を最大限最適化するためのオプション(複数のオプションを組み合わせた「セット・オプション」があります。以下は、pgfortran を使用した場合の例ですが、コンパイラのオプションの設定方法は、他の言語コンパイラでも同じです。一般に、デフォルトで指定するオプションは、以下の STEP 1 のものをお使い下さい。
pgfortran/pgcc/pgc++ -fast -Minfo test.f pgfortran/pgcc/pgc++ -O2 -Minfo test.f (PGI 13.1から -O2 でも -fast と同等な機能オプションとなります) あるいは、 pgfortran/pgcc/pgc++ -fast -Mipa=fast,inline -Minfo test.f (IPA最適化を有効化) Linux版のpgc++コマンドは、 PGI 13.1から、OS X版は、PGI 15.1 から。それ以前は、pgcppのみ。 Windows 版は pgcpp or pgCC コマンドのみ(PGI 16.1以降当該コマンドが廃止されました)
-fast 等の複合オプションの内容を知りたい場合は、-flags オプションを付けて確認する pgfortran -fastsse -flags -fastsse == -fast -fast Common optimizations; includes -O2 -Munroll=c:1 -Mnoframe -Mlre -Mautoinline == -Mvect=sse -Mcache_align -Mflushz -Mpre
性能を最大化するために、常に、-fastsse あるいは、-fast オプションを付けてコンパイルして下さい。さらに、
-Mipa=inline オプションを追加すると手続き間を含めた自動インライン化が有効となり、性能向上が望めます。特に、C/C++プログラムでは、インライン化は大きな性能向上が期待できます。PGI 7.1 以降では、64ビット用の C/C++ コンパイラの -fast 複合オプション(-fastsse)の中に、-Mautoinline オプションが加わりました。 C/C++ コンパイルで、-fast (-fastsse)を指定すると、自動インラインモードでコンパイルされます。
もう一つ、C/C++ の場合は、–Msafeptr と言うコマンド・オプションは、ポインタ間でそのメモリ上の場所の重なりが存在しない場合(no pointer aliasing) 、C/C++プログラムの性能を劇的に向上させます。但し、このオプションは、デフォルトでは有効ではありませんので、こうしたポインタ間の alias 依存性がない(重なりがない)場合は、
-Msafeptr オプションを指定するとさらなる最適化が行われます。
PGI 13.1(2013年)から -Oオプションの最適化レベルの一部変更
最適化レベルを指定する -O、-O2 の内容が変更されました。これは、PGI 13.1 から適用されています。以下にその概要を記します。下線部分が従来のものとの変更点です。
pgcc/pgc++ -fast -Mipa=fast,inline -Msmartalloc -Minfo test.c (test.cpp) Linux版のpgc++コマンドは、 PGI 13.1から、OS X版は、PGI 15.1 から。それ以前は、pgcppのみ。 Windows 版は pgcpp or pgCC コマンドのみ(PGI 16.1以降コマンドが廃止されました)
C++プログラム においては、特にインライン展開は重要であるため、-Mipa=inline オプションを使用しない場合は、明示的に自動インライン化を行うための -Minline=levels:10 オプションを常に使用することを強く推奨します。また、 --no_exceptions は、例外処理を無効にするオプションですが、これを指定すると性能向上する場合が多いです。(なお、この --no_exceptions を伴ってコンパイルしたプログラム自体が例外処理を行っている場合は、実行時にエラーとなりますのでご注意ください) PGI 11.0以降、C++コンパイラは、低コスト例外処理のハンドリング(--zc_eh)をデフォルトとしました。C/C++ プログラムに対しては、-Msmartalloc (Linux上のみ)も有効です。これは、最適化されたメモリ割付機能を使用することを指示するものです。
pgc++ -fast -Minline=levels:10 ---no_exceptions -Minfo test.cpp Linux版のpgc++コマンドは、 PGI 13.1から、OS X版は、PGI 15.1 から。それ以前は、pgcppのみ。 Windows 版は pgcpp or pgCC コマンドのみ(PGI 16.1以降コマンドが廃止されました)
-fast : -O2 -Munroll=c:1 -Mnoframe -Mlre –Mpre -Mautoinline
-fastsse : -fast -Mvect=sse -Mscalarsse -Mcache_align -Mflushz
なお、このオプションの中で、 -Mlre オプションは、loop-carried redundant removal と言う最適化手法です。loop-carried とは、ループ iteration 処理内と言う意味で、この中で共通数式(冗長数式)あるいは冗長な配列の参照を削除する最適化となります。たまに、この高度な最適化によって、数値結果に差異が生じる場合があります。この場合は、以下のようにして、-Mlre の最適化のみを抑止することが可能です。-fastsse の後に -Mlre=noassoc を指定することにより、-Mlre 最適化が抑止されます。同様に、-Mpreオプションも冗長演算部の削除を行うものですが、-Mnopreによって抑止されます。
pgfortran -fastsse -Mlre=noassoc ....
※PGI 7.0 以降の 64ビットCPUターゲットに対するコンパイル環境
-fast オプションは、従来の -fastsseオプションと同じ機能を有するオプションに変更しました。従来の -fast と等価な機能として、-nfast と言うオプションが新設されました。
※PGI 7.1 以降の 64ビットCPUターゲットに対するコンパイル環境
C/C++ コンパイラの -fast 複合オプションの中に、-Mautoinline オプションが加わりました。
上記の -fast あるいは、-Mipa オプションに関してはコンパイル時だけでなく、リンク時においても指定する必要があります。特に Makefile 等で、コンパイルフェーズとリンクフェーズを分けて行う場合は、リンケージのオプションにも同じように指定してください。リンク時において、上記のオプションを付けない場合、こちらに示すようなエラーが発生します。
pgfortran -fast -Mipa=fast -O3 -Mvect=prefetch=d:8 -Minfo test.f
性能最適化のオプションを使い分ける際は、必ず、それぞれのオプションを指定して、性能を評価してください。PGI に限らず、コンパイラ共通の特性により、場合によっては遅くなる場合もあるため、一番最速なオプションを評価し使用して下さい。
【プロセッサのTLBエントリ数のチューニング オプション】 pgcc/pgc++/pgfortran -fast -Msmartalloc=huge:448 {source_file} 【オプション】 -M[no]smartalloc[=huge|huge:<n>|hugebss]
huge : huge page のランタイムライブラリをリンクします
huge:<n> : huge page のランタイムライブラリをリンクし、使用されるページの数の限度を n に設定します
hugebss : huge page の中に BSS セクションを置きます
huge サブ・オプションは、それ自身、必要とされる huge page の数をアロケートしようとします。Huge page の数は、:n サブ・オプションで制限を設けることができ、あるいは、環境変数 PGI_HUGE_SIZE でも設定できます。hugebss は、プログラムの初期化されていないデータセクションを huge page の中に置きます。
上記の -Msmartalloc オプションは、コンパイル時とリンク時の両方で指定する必要があります。特に Makefile 等で、コンパイルフェーズとリンクフェーズを分けて行う場合は、どちらにも本オプション指定してください。
【インライン展開される側のソースライン数 約1000行まで許す】 pgcc/pgc++/pgfortran -fast -Minline=size:1000 {source_file} 【インライン展開される多重レベル数】 pgcc/pgc++/pgfortran -fast -Minline=levels:3 {source_file} 【複数のサブオプションを組み合わせる場合】 pgcc/pgc++/pgfortran -fast -Minline=size:1000,levels:3 {source_file}
-Minline[=[lib:]<inlib> | [name:]<func> | except:<func> | size:<n> | levels:<n> ] [lib:]<inlib> "inlib"ライブラリの中の関数を抽出してインライン展開する [name:]<func> 関数"func"をインライン展開する except:<func> 関数"func"をインライン展開しない size:<n> インライン対象のソース行数 n 以下のものをインライン展開 levels:<n> インライン展開される関数のレベル数
コンパイラのオプションだけではなく、ソースプログラムに直接コンパイラへの最適化指示を行うためのディレクティブも用意されています。以下の例は、メモリ階層でのデータ・プリフェッチを明示的に指示するための例です。
real*8 a(m,n), b(n,p), c(m,p), arow(n) ... do j = 1, p cmem$ prefetch arow(1),b(1,j) cmem$ prefetch arow(5),b(5,j) cmem$ prefetch arow(9),b(9,j) do k = 1, n, 4 cmem$ prefetch arow(k+12),b(k+12,j) c(i,j) = c(i,j) + arow(k) * b(k,j) c(i,j) = c(i,j) + arow(k+1) * b(k+1,j) c(i,j) = c(i,j) + arow(k+2) * b(k+2,j) c(i,j) = c(i,j) + arow(k+3) * b(k+3,j) enddo enddo