リンケージに関する有用なオプション
PGI コンパイル リンク時オプション
PGI の F77, F2003, C, C++ のコンパイラを使用してプログラムを開発する際に、リンク時の有用なオプションを以下に示します。以下は、主に、pgfortran を使用した場合の例ですが、コンパイラのオプションの設定方法は、他の言語コンパイラでも同じです。
2012年2月3日更新 Copyright © 株式会社ソフテック
リンク処理における有用なオプション
■ リンク時における外部ライブラリの指定
Linux
$ pgfortran -fastsse -o a.out test.f -L/opt/lib -lacml64
Windows
$ pgf95 -Minfo -fastsse -L"C:/Program Files (x86)/Intel/.../mkl/lib/intel64" \
mkl_intel_lp64.lib mkl_pgi_thread.lib mkl_core.lib -mp pgi_mm.f -o pgi_mm.exe
-
-L オプションは、コンパイル時の様々な情報を出力するためのオプションです。一般には、上記のとおりサブフラグなしで指定することで、ほとんどの最適化情報が得られます。
- (Linux) -l は、リンクすべきライブラリ名を指定します。上記の例では、libacml64.a と言うライブラリをリンクせよと言う指示になります。ライブラリ・ファイル名の上位の 'lib' と末尾の '.a' を記述する必要はありません
- (windows)ライブラリ・ファイル名(***.lib)をそのまま、コマンドリストに記述します。
■ 動的な shared library を含まない実行モジュールを作成する(Linux、Windows)
$ pgfortran -fastsse -Wl,-Bstatic test.f
$ pgfortran -fastsse -Bstatic test.f
- 一般に、Linux 上の実行モジュールの形式は、システム的に共通な shared library は動的なものとしてリンクされ、実行時に必要なライブラリを読み込んで実行する形式となっています。一般的な shared library の名前のコンベンションは、libpgc.so と言った .so と言うサフィクスが付けられています。
- 同様に、Windows 環境においても実行時に Dynamic Link Library(DLL) を必要とする動的リンク形式で動作する場合が多いです。Windows 版の PGI 7.0 までは、実行形式モジュールが、PGI の提供するDLLファイル (pg.dll と Microsoft(R) のマルチスレッド対応のランタイムライブラリ)を必要としましたが、PGI 7.1 以降は、静的ライブラリ形式の実行モジュールの生成がデフォルトとなりました。また、明示的に、静的ライブラリをリンクする際は、-Bstatic オプションを指定します。また、その逆に、DLL を必要とする実行モジュールを生成する際は、-Bdynamic を指定します。Windowsでは、これらのオプションは、コンパイル時並びにリンク時の両方に指定する必要があります。
- コンパイラをインストールしたマシン上で実行する分には、この動的ライブラリを自動的に取り込みますが、作成した実行モジュールを PGI コンパイラがインストールされていない別の Linux システム上で動かそうとした場合、 PGI の動的ライブラリ(libpgc.so、pg.dll 等)が存在しないため動作しません。そこで、実行モジュールを生成する際に、動的ライブラリのリンクではなく静的なライブラリ(実態のあるライブラリ)を全てリンクして生成する要求が出てきます。
-
-Wl,-Bstatic は、静的なライブラリをリンクし、どこでも動作可能な実行モジュールを作成するためのオプションです。但し、この実態のある静的ライブラリをリンクしますので、モジュールのサイズは大きくなります。まお、PGI 5.1 リリース以降は、同様なコンパイルオプションとして、 -Bstatic が提供されております。
(注意) 静的なリンク方法で、リンク時に未解決な参照ルーチンがあるというメッセージでエラーになる場合があります。これに関しては、こちらのページをご参考にしてください。
- Linux において、-mcmodel=medium オプションを使用してコンパイルしたオブジェクトは、静的なリンクはできません。これは、linux86-64 プログラミングモデル上での制約であり、PGI コンパイラ特有の制約ではありません。
- リンク操作に関する裏技に関しては、こちらのページにて、詳細に説明しています。
■ PGI専用ライブラリのみ静的にリンクし、Linuxシステムライブラリは動的にリンク (Linux)
$ pgfortran -fastsse -Bstatic_pgi test.f
- PGI が提供する専用ライブラリは「静的リンク」で行い、Linux のシステム依存ライブラリは、ダイナミックにリンクさせるためのオプションです。これは PGI 6.2 から新設されたオプションです。このオプションで生成された実行モジュールは、他の Linux システム(OSのglibcバージョン等が同じもの)においても、PGI が提供する専用シェアードライブラリをコピーすることなく実行できる利点があります。
■ 32bit Linuxで 1GB を越えるメモリを使用するFortranプログラムを実行したい(Linux)
$ pgfortran -fastsse -Wl,-Bstatic test.f
$ pgfortran -fastsse -Bstatic test.f
- 32bit Linux OS では、一般に、使用可能なメモリ空間の上限は 2GBですが、実際のデフォルトでは 1GB までのユーザ・メモリ空間を利用できる実行モジュールしか作成できません。しかし、コンパイルオプション "-Wl,-Bstatic" を用いて静的ライブラリを用いる実行モジュールを作成した場合、1 GB を超えるプログラムの実行モジュールを作成することが可能です。本オプションは、コンパイラが暗黙に用いる動的ライブラリを用いず、強制的に全て静的リンクします。いわゆる、1GB の壁は、動的ライブラリをメモリマップ上に置くポイントが、1GB ポインタであることによる問題です。動的ライブラリを用いない静的リンクにしますと、この制約がなくなります。
なお、1GB を越えるメモリ量を扱う Fortran プログラムを動かすためには、マシン自体にも十分なメモリ量(物理メモリ + swap メモリで 1GB 以上)を確保することも必要です(プログラムが必要とするメモリ量よりも、物理メモリ + swap メモリ量が少ないと正常に動作しません)。
■ リンケージ・マップとクロスリファレンスを出力する
$ pgfortran -fastsse -m -Wl,'-cref' test.f (Linux)
$ pgfortran -fastsse -m test.f (Windows)
-
-m オプションを付加することにより、ld コマンドによるリンケージ・マップとクロスリファレンスが標準出力に出力されます。Windows の場合は、*****.map と言うファイル名で保存されます。
-
-S オプションはリンケージ処理を行わない。このコマンド実行後、Test.s と言うアセンブラ ・リスティング・ファイルに、対応するソース・コードも注釈される。
-
-Mkeepasm は、生成されたアセンブルのリスティングを xxxx.s ファイルに出力します。
■ Windows におけるスタックサイズの調整
$ pgfortran -fastsse -Wl,-stack:N test.f
(PGI 7.0 以降)
$ pgfortran -fastsse -stack={ (reserved bytes)[,(committed bytes)] }{, [no]check } test.f
- Windows x64上では、以下のコンパイル・オプションでスタックサイズを指定します。Nは、必要とする任意のスタックサイズ値を指定します。
-Wl,-stack:N
- PGI 7.0 以降では、Windowsのみに有効な以下の -stack オプションが新設されました。
-stack={ (reserved bytes)[,(committed bytes)] }{, [no]check }
-stack を指定しない場合のデフォルトは、以下のとおりです。
Win32 : -stack:2097152,2097152、2MBがデフォルトで設定されます。
Win64 : デフォルトの設定はありません。
例: pgfortran -stack=524288,262144,nocheck myprog.f
プログラムの実行において、全体でトータル524,288 stack bytes (512KB)の領域を予約し、各ルーチンのためにOSが割り当てるスタックエリアとして262,144 stack bytes (256KB)を指定します。また、ルーチンに入る際のスタックの初期化を行わないようにnocheck引数をコンパイラに指示すると言う指定の方法です。
reserved bytes :プログラムで使用するトータル・スタックサイズ値を指定
committed bytes :各ルーチンのためにOSが割り当てるスタックエリアのサイズを指定。
デフォルトは 4096バイト。
[no]check :ルーチンに入る際にスタックの初期化を行うコードを生成するか、
行わないコードの生成かの指示を行う。”check”がデフォルトです。
スタック初期化コードは、「ルーチンのスタックサイズ」が committed bytes を超えたときに必要とされます。指定したcommitted bytes が reserved bytes に等しいか、あるいは、各ルーチンで必要とされるスタックバイト数に等しいとき、stack=nocheck オプションを指定して、スタック初期化コードの生成を抑止することができます。こうすることによって、コンパイラは十分なコミットスタックスペースを指定しているものと理解し、プログラムはそれ自身のスタックサイズの管理を必要とされません。
(注意)
-stack=(reserved bytes),(committed bytes) はリンク時のオプションです。
-stack=[no]checkは、コンパイル時のオプションです。