形状引継ぎ配列は遅め
tniina さんのブログ記事で面白いものがあったので下記にリンクはらさせていただきます。
in-neuro.hatenablog.com in-neuro.hatenablog.com
結論編を読まずに問題提起篇に脊髄反射コメントしてしまいました、テヘ。 結論篇にアセンブリを読み込んだ詳しい分析が書かれています。勉強になります。
記事本来は、ループ変数に 32bit 変数を使うか 64bit 変数を使うかで、32bit の方に余分な操作が必要ではないかということが主眼でしたが、Fortran の場合配列引数を F90 からの (:) による形状引継ぎ配列にすると、機械語レベルで余分な命令が大量に生成されるという別の問題が起きていました。
FORTRAN77 から Fortran90 に書き換えると SUBROUTINE 呼び出しがモッサリ遅くなることがあって、大抵原因は F77 の整合配列を F90 式に形状引継ぎ配列に直したためらしいことは、整合配列に戻すと F77 と同レベルの速さに戻ることから分かります。
F90 の形状引継ぎ配列は、F77 の整合配列と違って、配列のサイズを別に引数として渡す必要が無いので便利なのですが、渡された配列が記憶領域上で連続に並んでいない場合(例:a(::2) のようなとびとび配列へのポインタを渡す場合)でも大丈夫という高機能性が災いして、安全策を取って F77 のような最適化を抑制していると言われています。
なお Fortran 2008 で形状引継ぎ配列に対する記憶領域上の連続性を保証する cotiguous 属性が導入されて F77 的な最適化が可能になりました。
アセンブリでの比較
tniina さんのブログで紹介されているオンライン・コンパイラ Compiler Explorer でアセンブリを見ることが出来るようなので、1.形状引継ぎ配列、2. 形状引継ぎ配列+contiguous 属性、3. 整合配列 32bit、4.整合配列 64bit の4つの場合を tniina さんの例題におんぶにだっこで利用させてもらって比較してみます。
contiguous 属性を付けると、つけない場合に比べて前処理が不要になって大幅に短いコードになりますが、それでも F77 に比べて1個余計な命令が入っています。
F77 はとかく嫌われていますが、ほとんど静的で機能が低い分最適化しやすいので、おじさん達が 77 に固執するのも分からなくはないです。
NANA MIZUKI LIVE EXPRESS(Blu-ray)
- 発売日: 2020/03/25
- メディア: Blu-ray