2025.10.15

Fortranでのファイル入出力が遅い

Fortran (ifort/ifx) プログラムにおいてファイル入出力に時間を要する場合、以下の方法によって入出力を高速化できる可能性があります。

 

ファイル数やopen/close/read/write回数を削減する

open/close/read/writeなどのファイル操作はコストを要するため、高頻度に実行するとボトルネックになる可能性があります。例えば時間発展シミュレーションの場合は、1時間ステップごと新たなファイルを生成するのではなく、1つのファイルに追記することをご検討ください。

 

read/writeも小さい単位で多数回実行するより、可能な限りまとめて大きな単位で実行する方が高速です。例えば、配列変数をファイル出力する場合、以下のように要素ごとにwriteすると、大きな配列では長時間要します。

以下のように1つのwrite文で出力する方が高速です。

 

書式なし出力を用いる

open文の引数においてform="formatted"と指定すると書式付き出力 (テキスト形式)、form="unformatted"を指定すると書式なし出力 (バイナリ形式) が使用されます。また、formを指定していない場合は、デフォルトで書式付き出力が使用されます。書式付き出力はエディタ等で表示できる一方、計算機内部の浮動小数点数表現から文字列に変換するため、書式なし出力に比べ読み書きの性能が劣り、ファイルサイズが大きくなります。

 

大容量のデータを入出力する場合は、書式なし出力をお使いください。

 

Buffered I/Oを用いる

デフォルトでは、ifort/ifxでコンパイルされたプログラムではUnbuffered I/Oが用いられます。すなわち、writeの内容は即座にファイルシステムに書き込まれます。一方、Buffered I/Oと呼ばれる機能を有効にすると、writeの内容はメモリ上の領域 (バッファ) に蓄積され、バッファが満杯になった時点でファイルシステムに書き込まれます。これにより、ファイルシステムに対する操作の回数が削減され、writeの性能が向上します。readについても同様にバッファを活用することが可能です。

 

ifort/ifxにおいてBuffered I/Oを有効化するためには、以下の方法などがあります。詳しくはIntel Fortranコンパイラのマニュアルをご参照ください。

  • - ファイルのopen時にbuffered="yes"引数を指定する
  • - プログラムのコンパイル時にオプション-assume buffered_ioを指定する
  • - 実行時に環境変数FORT_BUFFERED=trueを設定する
  •  

    I/Oライブラリを使用する

    HDF5netCDF、ADIOS2などのI/Oライブラリは、I/Oを高速化するための様々な工夫に加え、メタデータの格納、データ圧縮、部分データの読み書きなど、便利な機能を多数備えています。当センターの計算機でも提供していますので、利用をご検討ください。

     

    2017.06.06

    MPIプロセスをノード毎にラウンドロビンで1プロセスずつ割り当てたい

    (質問の補足)
    OCTOPUS(24コア)4ノードでIntelMPIを使って並列計算を実行する際に、

    node 1: rank 0, 1, 2, ... , 24
    node 2: rank 25, 26, 27, ... ,48
    node 3: rank 49, 50, 51, ... ,72
    node 4: rank 73, 74, 75, ... , 96

    とするのではなく、

    node 1: rank 0, 4, 8, ..., 93
    node 2: rank 1, 5, 9, ..., 94
    node 3: rank 2, 6, 10, ..., 95
    node 4: rank 3, 7, 11, ..., 96

    としたいが、どのようにすればよいのか?
     
    (回答)
    OCTOPUS(24コア)4ノードで並列計算を実行する場合、ジョブスクリプトで

    #PBS -b 4
    mpirun {NQSII_MPI_p} -ppn 1 -n 80 ./a.out

    と指定してください。
    IntelMPIはmpiexecの-ppnオプションに指定した値の数だけ、連続したプロセスをノード毎に割り当てます。
    したがって、-ppn 1と指定していただくことで、1ノードに1プロセスずつ割り当てるようになります。
     

    「man mpiexec」コマンドで表示される-ppnオプションの解説(IntelMPI)

    -perhost <# of processes>, -ppn <# of processes, -grr <# of processes>
    Use this option to place the specified number of consecutive MPI processes on every host in the group using round robin scheduling.

    2014.12.18

    過去のチューニング事例を教えてください

    過去に、(株)日本電気と本センターが協力してチューニングした事例をご紹介いたします。
    なお、利用者番号での認証が必要となっておりますので、ご了承ください。

    2009年度チューニング報告
    2013年度チューニング報告

    2014.07.14

    I-CACHE、O-CACHEについて教えてください。

    I-CACHE、O-CAHCEとは、SXにてプログラムを実行後に出力される「プログラム情報※1」内の項目の一つです。

     名称)
      I-CACHE : 命令キャッシュ(ミス)
      O-CACHE : オペランドキャッシュ(ミス)

     意味)
      スカラユニット用のキャッシュ(I-CACHE、O-CACHE 両方共)。
      「プログラム情報」ではプログラム中でベクトル化されていない、
      スカラ処理部分におけるキャッシュミス時間を表示している。

     キャッシュ構成)
      スカラマシンの有している L1 キャッシュと同等の機能。
      SX-9 の場合は32KB(256B/キャッシュライン * 64エントリ * 2way)を有している。

     チューニング方法)
      1.スカラ処理部分を可能な限りベクトル化する。ベクトル化することにより
        キャッシュミス時間は自動的に削減される。
      2.極限までベクトル化した後もキャッシュミス時間が残る場合、
        スカラマシンと同様にキャッシュのスラッシング対策を行う。
        具体的には、O-CACHE値等で 2way で追い出し(スラッシング) が
        発生しているかどうかを確認し、スラッシングが発生している場合は
        配列をずらすことでスラッシングを回避してキャッシュヒット率を高める。
        これによりキャッシュミス時間を削減する。

    ※1プログラム情報
      ジョブスクリプトに「setenv F_PROGINF DETAIL」を指定する事で標準エラー出力に出力

     出力例(英語):
    ****** Program Information ******
    Real Time (sec) : 1.055745
    User Time (sec) : 0.009741
    Sys Time (sec) : 0.019627
    Vector Time (sec) : 0.000047
    Inst. Count : 1887787.
    V. Inst. Count : 2284.
    V. Element Count : 324751.
    FLOP Count : 26141.
    MOPS : 226.902166
    MFLOPS : 2.683605
    A. V. Length : 142.185201
    V. Op. Ratio (%) : 14.692927
    Memory Size (MB) : 192.031250
    MIPS : 193.798070
    I-Cache (sec) : 0.002054
    O-Cache (sec) : 0.001399
    Bank Conflict Time
    CPU Port Conf. (sec) : 0.000010
    Memory Network Conf. (sec) : 0.000007

    Start Time (date) : Wed Nov 17 00:24:43 JST 2010
    End Time (date) : Wed Nov 17 00:24:44 JST 2010

     出力例(日本語):
      (環境変数「setenv LANG japan」を指定)
    ****** プログラム情報 ******
    経過時間 (秒) : 1.044924
    ユーザ時間 (秒) : 0.010063
    システム時間 (秒) : 0.020361
    ベクトル命令実行時間 (秒) : 0.000050
    全命令実行数 : 1891084.
    ベクトル命令実行数 : 2284.
    ベクトル命令実行要素数 : 324751.
    浮動小数点データ実行要素数 : 26146.
    MOPS 値 : 219.969293
    MFLOPS 値 : 2.598231
    平均ベクトル長 : 142.185201
    ベクトル演算率 (%) : 14.671042
    メモリ使用量 (MB) : 192.031250
    MIPS 値 : 187.924476
    命令キャッシュミス (秒) : 0.001853
    オペランドキャッシュミス (秒) : 0.001798
    バンクコンフリクト時間
    CPU ポート競合 (秒) : 0.000008
    メモリネットワーク競合 (秒) : 0.000007

    開始時刻 (日付) : 2010年 11月 30日 火曜日 15:25:14 JST
    終了時刻 (日付) : 2010年 11月 30日 火曜日 15:25:15 JST