ホーム > サポート > FAQ(よくある質問) > コンパイラによるSIMD化の促進について

コンパイラによるSIMD化の促進について

最終更新日:2018年6月26日
最近の主要なコンパイラは自動的にSIMD命令を生成する機能を備えていますが、コンパイラの判断基準の都合などにより、SIMD化できそうなのにSIMD化してくれない、ということがしばしば発生します。そのような場合には、コンパイラオプションを見直す、プログラムをよりSIMD化しやすい構造に書き換える、指示文の挿入を行う、といった対応によってSIMD化の促進を行ってください。なお、SIMD命令を使えば必ずプログラムの実行時間が短縮されるとは限りません。レジスタ間のデータ移動が必要であったり、SIMD処理時にはCPU動作周波数が低下したり、などの要因によって、SIMD化は進んだのに性能は低下した(実行時間は増加した)ということもあり得ますので注意してください。

IntelコンパイラによるSIMD化について

Intelコンパイラによる最適化処理の情報を得るためには-qopt-reportで始まる各種オプションが有用です。特に、IntelコンパイラがソースコードのどこをどのようにSIMD化したかという情報は、コンパイルオプションに -qopt-report-phase=vec を指定してコンパイルし、出力された*.optrptファイルを見ればわかります。

Intelコンパイラをスーパーコンピュータ納入業者である富士通株式会社の推奨最適化オプション「-ipo -O3 -no-prec-div -fp-model fast=2 -xHost」で利用した場合、-xHostが-xCORE-AVX512相当となり、ある程度単純な構造のプログラムについてはコンパイラが自動的にAVX512命令を生成してくれます。
しかしIntelコンパイラがSIMD化の判断をするため、対象のプログラムによってはAVX512命令を生成してくれるとは限りません。参考資料 によると、インテルコンパイラ18(module load intel/2018環境)では、-xCORE-AVX512オプションはデフォルトでは保守的(AVX512命令をあまり積極的に出力しない)な振る舞いになっています。より積極的にAVX512命令を出力させるためには、-xHost(および-xCORE-AVX512)の代わりに-xCOMMON-AVX512オプションを指定する、または-qopt-zmm-usage=highを追加指定する必要があります。ただし、この指定を行うと、むしろ本来はSIMD化に適していないループまでSIMD化してしまうことも多くなるため注意せねばなりません。(SIMD化の際にメモリアドレスの調整や余りの処理をするpeelループやreminderループまで、半ば無理矢理にSIMD化しようとしたりしてしまうようです。)
コンパイラがSIMD化してくれない部分をより積極的にSIMD化させるようコンパイラに指示を行うには、#pragma omp simd 指示文(Fortranの場合には!$omp simd)を使用してください。また、SIMD命令は対象配列のメモリアドレスがアドレス境界に揃っているかなどの条件が揃っている場合とそうでない場合とで性能差が生じます。ifortのコンパイラオプションに-align array64byteを指定する、配列宣言時にattributeを付加する、などの対応によりベクトル化を促進させることもできます。参考資料

富士通コンパイラによるSIMD化について

富士通コンパイラを使用する場合は-O2以上の最適化オプション指定時にSIMD化が行われます。-Kfastも-O3を含むため、SIMD化が行われます。SIMD化の状況を確認するためには-Koptmsg=2も追加します。SIMD化が思うように行われない場合は、-Ksimd=2を指定することで改善する場合があります。(-O2以上の最適化オプション指定時は-Ksimd=1が含まれます。-Ksimd=2にするとif文を含む命令に対するSIMD化などが追加されるため、SIMD化が促進されます。)命令単位でのSIMD化指示を行う場合はocl simd指示文を使用してください。(詳細については、ポータルから入手可能な使用手引書を参照してください。)