c++ users...

96
C++ 言語使用手引書

Upload: others

Post on 09-Apr-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

C++ 言語使用手引書

はじめに

本書の目的

本書は、以下に示すオペレーティングシステム上で動作する C++ 言語処理系 ( 以降、本処理系と呼びます ) の使用方法を記述しています。

・ Solaris™ オペレーティングシステム ( 以降、Solaris OS)

また、本書は、以下の C++ 言語規格書および OpenMP 仕様を元に、本処理系で拡張した言語仕様についても記述しています。

・ "Programming languages - C++" (ISO/IEC 14882:1998(E))

本書では本 ISO 規格を、一般的な表現として C++ 言語規格と呼んでいます。

・ OpenMP Application Program Interface Version2.5 (May 2005)

この規格で定義された仕様を OpenMP 仕様と呼びます。

本書の読者

本書は、C++ 言語規格書で規定された言語仕様を前提に記述しています。規格仕様については、C++ 言語規格書を参照するか、または規格準拠の市販本をお読みください。本書は、本処理系を使用して、C++ プログラムを処理する人および C++ プログラムを作成する人を対象に記述しています。本書を読むにあたっては、UNIX コマンド、ファイル操作およびシェルプログラミングの基本的な操作知識が必要です。

本書の構成

第 1 章 処理手続き本処理系を使用して、C++ プログラムを処理する場合の手続きについて記述しています。

第 2 章 翻訳から実行までC++ プログラムの翻訳から実行までの手続きについて記述しています。

第 3 章 逐次 適化機能逐次 適化機能を使用する場合に、利用者が注意しなければならない事項について記述しています。

第 4 章 並列化機能自動並列化機能や OpenMP 仕様を利用したプログラムの高速化について、利用者が注意しなければならない事項について記述しています。

第 5 章 出力情報本処理系が出力する情報について記述しています。

第 6 章 言語仕様C++ 言語規格の言語仕様を元に、本処理系で拡張した言語仕様について記述しています。

第 7 章 言語間結合における注意事項Fortranおよび C言語で記述されたプログラムと結合する場合の注意事項について記述しています。

付録 A 高速数学関数本処理系が提供する高速数学関数について記述しています。

付録 B 制限事項および注意事項本処理系の制限および利用する上での注意事項を記述しています。

付録 C ParallelnaviParallelnavi 固有機能について記述しています。

本書の読み方

本処理系を使用するにあたり、 初に「付録 B.4 環境変数の設定」をお読みください。本処理系を使用して、C++ プログラムの翻訳、結合編集、実行およびデバッグを行う場合、「第1 章 処理手続き」および「第 2 章 翻訳から実行まで」をお読みください。また、本処理系の

適化機能を使用する場合、「第 3 章 逐次 適化機能」をお読みください。並列化機能を使用する場合、「第 4 章 並列化機能」をお読みください。本処理系が出力する情報については、「第 5 章出力情報」をお読みください。C++ 言語規格の言語仕様を元に、本処理系で拡張した言語仕様を知りたい場合、「第 6 章 言語仕様」をお読みください。 他の言語で記述されたプログラムと結合する場合、「第 7 章 言語間結合における注意事項」をお読みください。本処理系で用意している高速数学関数を知りたい場合、「付録 A 高速数学関数」をお読みください。 本処理系の制限事項および注意事項を知りたい場合、「付録 B 制限事項および注意事項」をお読みください。Parallelnavi 固有機能について知りたい場合、「付録 C Parallelnavi」をお読みください。

本書の注意事項

本書では、以下の記号および用語を用いて機能を記述しています。[ 項目 ] : その項目を省略できることを意味します。[ 項目 1| 項目 2] : 項目 1、項目 2 のどちらかを指定できることを意味します。 項目が三つ以上指定されている場合も同様です。{ 項目 1| 項目 2} : 項目 1、項目 2 いずれか一つを文脈により選択しなければならないことを意味します。項目が三つ以上指定されている場合も同様です。項目・・・ : 項目を任意の個数繰り返して指定できることを意味します。

商標

UNIX は、米国およびその他の国におけるオープン・グループの登録商標です。Sun、Solaris は、米国 Sun Microsystems,Inc. の商標です。すべての SPARC 商標は、米国 SPARC International,Inc. のライセンスを受けて使用している同社の米国およびその他の国における商標または登録商標です。SPARC 商標が付いた製品は、米国 Sun Microsystems 社が開発したアーキテクチャに基づくものです。OpenMP は、OpenMP Architecture Review Board の商標です。INFORMIX は、米国 Informix Software,Inc. の登録商標です。他の各製品名は、各社の商標、または登録商標です。

著作権

Copyright 1995- Globetrotter Software,Inc.Copyright 1995- Software Research Associates,Inc.All Rights Reserved.All Rights Reserved, Copyright(c) 富士通株式会社 1999-2006

お願い

・ 本書を無断で転載しないようお願いします。

・ 本書は予告なしに変更されることがあります。

目次

第1章 処理手続き..................................................... 1

1.1 翻訳...........................................................................11.2 結合編集.......................................................................11.3 実行...........................................................................11.4 デバッグ.......................................................................11.5 64 ビットアドレスモードの実行可能プログラムの作成 ..............................1

第 2 章 翻訳から実行まで............................................... 3

2.1 翻訳コマンド ...................................................................32.1.1 翻訳コマンドの形式 .........................................................32.1.2 翻訳コマンドの入力ファイル .................................................32.1.3 翻訳コマンドの復帰値 .......................................................3

2.2 翻訳時オプション...............................................................42.2.1 翻訳時オプションの形式.....................................................42.2.2 翻訳時オプションの意味.....................................................52.2.3 翻訳時オプションの注意事項.................................................22

2.3 翻訳時プロフィルファイル.......................................................232.4 実行の手続き...................................................................232.4.1 実行時環境変数.............................................................242.4.2 実行時オプションの指定方法.................................................242.4.3 実行時の注意事項...........................................................24

第 3 章 逐次 適化機能................................................. 27

3.1 適化の概要...................................................................273.2 標準 適化.....................................................................273.2.1 共通式の除去...............................................................273.2.2 不変式の移動...............................................................283.2.3 演算子の強さの縮小.........................................................283.2.4 ループ・アンローリング.....................................................293.2.5 ソフトウェア・パイプライニング.............................................30

3.3 拡張 適化.....................................................................303.3.1 インライン展開.............................................................303.3.2 評価方法を変更する 適化...................................................303.3.3 ポインタの 適化...........................................................32

3.4 適化機能の活用方法...........................................................333.4.1 適化制御行 (OCL) の利用...................................................333.4.2 プロファイル情報の利用.....................................................353.4.3 実行マシン属性の選択.......................................................353.4.4 適化機能の選択の目安.....................................................36

第 4 章 並列化機能..................................................... 37

4.1 並列処理の概要.................................................................374.1.1 並列処理とは...............................................................374.1.2 並列処理の効果.............................................................374.1.3 並列処理で効果を得るための条件.............................................384.1.4 本処理系の並列機能の特徴...................................................38

4.2 自動並列化.....................................................................384.2.1 翻訳・実行の方法...........................................................384.2.2 並列化プログラムのチューニング.............................................414.2.3 自動並列化処理の詳細.......................................................41

4.3 OpenMP 仕様による並列化 ........................................................564.3.1 翻訳・実行の方法...........................................................56

4.3.2 処理系依存の仕様...........................................................604.3.3 プログラミングの注意事項...................................................614.3.4 他のマルチスレッドプログラムとの結合.......................................614.3.5 OpenMP プログラムのデバッグ ................................................614.3.6 並列実行情報...............................................................61

第 5 章 出力情報....................................................... 63

5.1 翻訳時情報.....................................................................635.1.1 ヘッダ.....................................................................635.1.2 ソースリスト...............................................................635.1.3 並列化メッセージ...........................................................655.1.4 統計情報...................................................................65

5.2 実行時情報.....................................................................665.2.1 トレースバック情報.........................................................665.2.2 高速数学関数のエラー.......................................................67

第 6 章 言語仕様....................................................... 71

6.1 long long 型 ...................................................................716.2 pragma 指令 ....................................................................726.3 ident 指令 .....................................................................726.4 assert 指令 ....................................................................726.5 unassert 指令 ..................................................................736.6 実装されていない言語仕様.......................................................73

第 7 章 言語間結合における注意事項..................................... 75

7.1 C 言語との結合 .................................................................757.2 Fortran との結合 ...............................................................75

付録 A 高速数学関数 ................................................... 77

付録 B 制限事項および注意事項 ......................................... 79

B.1 制限事項.......................................................................79B.1.1 OpenMP プログラムにおける制限 ..............................................79B.1.2 OpenMP プログラムのデバッグ情報生成 ( 翻訳時オプション -g) における制限 ......79

B.2 注意事項.......................................................................80B.3 移行上の注意事項...............................................................80B.3.1 -O4 ........................................................................80B.3.2 -Kgs および -Kpreload .......................................................80B.3.3 -p .........................................................................80B.3.4 ライブラリ.................................................................81B.3.5 非互換.....................................................................81

B.4 環境変数の設定.................................................................82B.4.1 コマンドの起動.............................................................82B.4.2 オンラインマニュアル.......................................................82B.4.3 Tools.h++ の利用 ...........................................................82

B.5 整合性.........................................................................82B.5.1 アプリケーションプログラムの整合性について.................................82

付録 C Parallelnavi ................................................... 83

C.1 ラージページ機能...............................................................83C.1.1 翻訳.......................................................................83C.1.2 実行.......................................................................84C.1.3 ラージページ機能を利用するプログラムの判定.................................84C.1.4 制約事項...................................................................84

C.2 CPU 数の管理 ...................................................................85

C.2.1 自動並列化向けスレッド数の決定.............................................85C.2.2 OpenMP 向けスレッド数の決定 ................................................85

C.3 スレッド間ハードウェアバリア機能...............................................86C.3.1 翻訳.......................................................................86C.3.2 実行.......................................................................86C.3.3 スレッド間ハードウェアバリア機能を利用するプログラムの判定.................87C.3.4 制約事項...................................................................87

図目次

4.1 並列処理のイメージ................................................ 374.2 並列処理による経過時間の短縮...................................... 384.3 ループスライスのイメージ.......................................... 414.4 ループスライスができないループの例................................ 424.5 多重ループでのループ交換.......................................... 434.6 ループの分割...................................................... 444.7 ループの融合...................................................... 444.8 リダクションによる自動ループスライス.............................. 454.9 回転数が小さく、演算数が少ないループ.............................. 464.10 関数の引用を含むループ........................................... 464.11 飛び出しのあるループ............................................. 464.12 serial 指示子のないプログラム例 .................................. 484.13 serial 指示子の使用例 ............................................ 494.14 parallel 指示子のないプログラム例 ................................ 494.15 parallel 指示子の使用例 .......................................... 504.16 disjoint 指示子のないループの例 .................................. 504.17 disjoint 指示子の使用例 .......................................... 504.18 temp 指示子のないプログラム例 .................................... 514.19 temp 指示子の使用例 .............................................. 514.20 independent 指示子のないループの例 ............................... 524.21 independent 指示子の使用例 ....................................... 524.22 reduction 指示子の使用例 ......................................... 534.23 noreduction 指示子の使用例 ....................................... 534.24 並列処理が入れ子になった場合..................................... 544.25 リダクションによる精度差......................................... 555.1 ヘッダの出力形式.................................................. 635.2 並列化表示の出力例................................................ 645.3 ループ・アンローリングの出力例.................................... 655.4 並列化メッセージの出力例.......................................... 655.5 統計情報の出力形式................................................ 655.6 トレースバックマップの出力形式.................................... 675.7 高速数学関数エラーにおける処置例.................................. 69

表目次

2.1 FCC コマンドの形式 ................................................ 32.2 入力ファイルの形式................................................ 32.3 FCC コマンドが設定する復帰値 ...................................... 42.4 -Kcpu との組み合わせ .............................................. 162.5 実行時環境変数.................................................... 243.1 適化制御行と有効範囲............................................ 333.2 適化制御行に指定できる 適化指示子.............................. 344.1 自動並列化用の 適化指示子一覧.................................... 475.1 高速数学関数のエラー処理.......................................... 67A.1 高速数学関数一覧.................................................. 77

第 1章 処理手続き

本章では、本処理系を利用して C++ プログラムを処理する場合の手続きについて説明します。

1.1 翻訳

利用者は、翻訳コマンドである FCC を使用して、C++ 言語で記述されたソースプログラムを翻訳します。 翻訳時には、オブジェクトプログラムの 適化などの豊富な機能が使用できます。 これらの機能は、翻訳時オプションとして FCC コマンドのオペランドに指定することにより、使用できます。

1.2 結合編集

翻訳コマンド FCC は、結合編集のためにリンカ(ld コマンド)を呼び出す機能を提供します。 利用者は、FCC コマンドを使用して、翻訳の過程で生成されたオブジェクトプログラムと C++ 言語ライブラリなどを結合編集させて実行可能プログラムを生成します。

ISO 準拠 C++ ライブラリ使用について以下の条件をすべて満足する場合、すべてのライブラリを動的に結合する必要があります。1)ISO 準拠 C++ ライブラリを使用している。2) ユーザ作成の動的ライブラリにコンストラクタが含まれ、そのコンストラクタ内で ISO 準拠C++ ライブラリを使用している。3) コンストラクタが含まれるクラスオブジェクトを外部に定義している。

1.3 実行

利用者は、FCC コマンドを使用して作成した実行可能プログラムを実行コマンドとして起動します。以下に、使用例として例題プログラム sample.cc を翻訳して、実行するまでの手続きを示します。

例題プログラム sample.cc #include <iostream.h>int main(void){ cout << "Hello, world." << endl; return 0;}

翻訳と結合編集 $ FCC sample.cc

実行$ ./a.out

結果 Hello,world.

1.4 デバッグ

C++ ソースプログラムのデバッグの方法として、プログラミング支援ツール (Parallelnavi 環境) あるいは fdb コマンド ( 非 Parallelnavi 環境 ) で提供されるソースレベルによるデバッグ機能があります。この機能を使用する場合は、C++ ソースプログラムを FCC コマンドの -g 指定で翻訳しておく必要があります。 なお、-g を指定した場合、-O、-Kparallel および PCH 関連オプションは無効となります。

1.5 64 ビットアドレスモードの実行可能プログラムの作成

64 ビットアドレスモードの実行可能プログラムは、-KV9 を指定することにより、作成することができます。

例 )64 ビットアドレスモードの実行可能プログラムの作成方法

1

C++ 言語使用手引書

$ FCC -KV9 foo.ccまたは$ FCC -KV9 -c foo.cc$ FCC -KV9 foo.o

64 ビットアドレスモードの実行可能プログラムを作成するにあたり、以下の注意事項があります。

・ -KV9 より後に、以下の翻訳時オプションを指定しないでください。もし、以下に示すオプションのうちいずれかが指定された場合、64 ビットアドレスモードのオブジェクトプログラムは作成されません(-KV9 が無効となり、32 ビット用のオブジェクトプログラムが作成されます)。

-Kfast, -Kfast_GP, -Kfast_GP2, -Kfast_VI

・ 64ビットアドレスモードのオブジェクトプログラムおよび実行可能プログラムは、 64ビットオペレーティングシステム上だけで作成することができます。

・ 64 ビットアドレスモードの実行可能プログラムは、64 ビットオペレーティングシステム上だけで実行することができます。

・ -KV9 を指定して翻訳されていないオブジェクトプログラムは、-KV9 を指定して結合編集できません。

2

第 2章 翻訳から実行まで

本章では、ソースプログラムを翻訳し実行するための手続きについて説明します。

2.1 翻訳コマンド

利用者は、FCC コマンドを使用することにより、ソースプログラムの翻訳から実行可能プログラムの作成まで行うことができます。FCC コマンドは、FCC コマンド行に指定された各種のオペランドを解析し、必要に応じてプリプロセッサ、コンパイラ、アセンブラ (as コマンド ) およびリンカ (ld コマンド ) を呼び出します。

2.1.1 翻訳コマンドの形式利用者は、FCC コマンドのオペランドとして、プリプロセッサ、コンパイラ、アセンブラおよびリンカに対するオプションの並びとファイル名を指定することができます。 ここで、プリプロセッサおよびコンパイラに対するオプションを翻訳時オプションといいます。コンパイラ (FCCコマンド )、アセンブラ (as コマンド ) およびリンカ (ld コマンド ) に対するオプションについては、man コマンドを使用して参照することができます。 「表 2.1 FCC コマンドの形式」に、FCCコマンドの形式を示します。

□ : 一個以上の空白が必要であることを意味します。

備考" オプションの並び " と " ファイル名の並び " の指定順序に制約はありません。例えば、" ファイル名の並び " の後に " オプションの並び " を指定してもかまいませんし、混在していてもかまいません。

2.1.2 翻訳コマンドの入力ファイル「表 2.2 入力ファイルの形式」に、FCC コマンドに入力ファイルとして指定できるファイルを示します。

2.1.3 翻訳コマンドの復帰値「表 2.3 FCC コマンドが設定する復帰値」に、FCC コマンドが設定する復帰値を示します。

表 2.1 FCC コマンドの形式

コマンド名 オペランド

FCC [ □オプションの並び ] □ファイル名の並び

表 2.2 入力ファイルの形式

ファイルの種別 ファイルのサフィックス 渡し先

C++ ソースファイル .cc, .C, .c, .cpp, .i,.cxx

プリプロセッサおよびコンパイラ

アセンブラソースファイル .s アセンブラ

オブジェクトファイル .o リンカ

3

C++ 言語使用手引書

2.2 翻訳時オプション

ここでは、FCC コマンドに指定できる翻訳時オプションの形式および意味について説明します。

2.2.1 翻訳時オプションの形式FCC コマンドのオペランドで翻訳時オプションを指定することができます。以下に、翻訳時オプションの形式を示します。

コンパイラ全般に関連するオプション[ -# ] [ -### ] [ -A- ] [ -Aname[(tokens)]] [ -Bc ] [ -C ] [ -c ] [ -Dname[=tokens] ] [ -dc ] [ -E ] [ -G ] [ -g ] [ -H ] [ -Idir ] [ -Ldir ] [ -lname ] [ -mt ] [ -opathname ] [ -P ] [ -Qc ] [ -Rdir ] [ -S ] [ -Uname ] [ -Wtool,arg1[,arg2,...] ] [ -Yitem,dir ] [ --ar ]

メッセージ関連オプション[ -j ] [ -V ] [ -w ] [ {--brief_diagnostics|--no_brief_diagnostics} ] [ --diag_error tag[,tag,...] ] [ --diag_suppress tag[,tag,...] ] [ --display_error_number ] [ --error_limit number ] [ {--for_init_diff_warning|--no_for_init_diff_warning} ]

適化関連オプション[ -Kopt ] [ -O[n] ] [ -x- ] [ -xfunc1[,func2,...] ] [ -xn ]

言語仕様関連オプション[ {--alternative_tokens|--no_alternative_tokens} ] [ {--anachronisms|--no_anachronisms} ] [ {--arg_dep_lookup|--no_arg_dep_lookup} ] [ {--array_new_and_delete|--no_array_new_and_delete} ] [ {--auto_instantiation|--no_auto_instantiation} ] [ {--bool|--no_bool} ] [ {--class_name_injection|--no_class_name_injection} ] [ {--const_string_literals|--no_const_string_literals} ] [ {--distinct_template_signatures|--no_distinct_template_signatures} ] [ --dollar ] [ {--early_tiebreaker|--late_tiebreaker} ] [ {--exceptions|--no_exceptions} ] [ {--explicit|--no_explicit} ] [ {--extended_variadic_macros|--no_extended_variadic_macros} ] [ --force_vtbl ] [ {--friend_injection|--no_friend_injection} ] [ {--implicit_include|--no_implicit_include} ] [ --incl_suffixes str ] [ --instantiate mode ] [ --library={aCmnst} ] [ --linkfortran ] [ {--long_lifetime_temps|--short_lifetime_temps} ] [ {--microsoft|--microsoft_16|--no_microsoft} ] [ {--microsoft_bugs|--no_microsoft_bugs} ] [ --microsoft_version value ] [ {--namespaces|--no_namespaces} ] [ {--new_for_init|--old_for_init} ] [ {--nonconst_ref_anachronism|--no_nonconst_ref_anachronism} ] [ {--nonstd_using_decl|--no_nonstd_using_decl} ] [ --norunpath ] [ {--old_specializations|--no_old_specializations} ] [ --pending_instantiations=N ] [ --preinclude filename ] [ {--rtti|--no_rtti} ]

表 2.3 FCC コマンドが設定する復帰値

復帰値 意味

0 正常に終了しました。

1 翻訳エラーまたはリンカでエラーが発生しました。

4

第 2 章 翻訳から実行まで

[ {--special_subscript_cost|--no_special_subscript_cost} ] [ --strict ] [ --suppress_vtbl ] [ {--typename|--no_typename} ] [ {--variadic_macros|--no_variadic_macros} ] [ {--wchar_t_keyword|--no_wchar_t_keyword} ]

PCH 関連オプション[ --create_pch fname ] [ --pch ] [ --pch_dir dir ] [ {--pch_messages|--no_pch_messages} ] [ --use_pch fname ]

2.2.2 翻訳時オプションの意味以下に、翻訳時オプションの意味を示します。FCC( コンパイラドライバ ) が識別不可能なオプションは、リンカに渡されます。

2.2.2.1 コンパイラ全般に関連するオプションここでは、翻訳で使用される一般的なオプションについて説明します。

-#FCC によって実行されるコマンドを表示します。ただし、プログラムの翻訳処理は行いません。

-###FCC によって実行されるコマンドを表示します。

-A-あらかじめ定義されたマクロ (__ で始まるものは除く ) と、あらかじめ定義されたアサーションをすべて無効にします。

-Aname[(tokens)]#assert 前処理指令の機能と同様、name を述語とし、指定された tokens と関連づけます。あらかじめ定義されたアサーションを、以下に示します。

・ system(unix)

・ cpu(sparc)

・ machine(sparc)

-Bcc には、dynamic または static を指定します。 -lx の指定に対して、-Bdynamic を指定した場合、リンカは 初に libx.so という名前のファイルを探し、次に libx.a という名前のファイルを探します。 -Bstatic を指定した場合、リンカは libx.a だけを探します。コマンド行では、各 -lx 指定に対して、本オプションを別々に切り替えて指定することができます。本オプションは、リンカに渡されます。

-C前処理の段階で通常削除される注釈を、前処理指令の行にあるもの以外、この段階では削除されないようにします。

-c翻訳処理の 後の段階である結合編集を行わないようにします。また、それまでに作成されたオブジェクトファイルが削除されるようなことはありません。

-Dname[=tokens]name を、#define 前処理指令のように、指定された tokens と関連づけます。 =tokens が省略された場合、1 が与えられます。あらかじめ定義されたマクロ名を、以下に示します。・ c_plusplus・ sparc・ sun・ unix

5

C++ 言語使用手引書

・ _BOOL (--bool が有効な場合 )・ _OPENMP (-KOMP が有効な場合、200505 が定義されます )・ _WCHAR_T (--wchar_t_keyword が有効な場合 )・ __ARRAY_OPERATORS・ __BUILTIN_VA_ARG_INCR・ __PRAGMA_REDEFINE_EXTNAME・ __EXCEPTIONS (--exceptions が有効な場合 )・ __FCC_VERSION (5.6 が定義されます )・ __RTTI (--rtti が有効な場合 )・ __STDC__・ __SVR4・ __'uname -s'_'uname -r'・ __cplusplus・ __unix・ __sun・ __sparc・ __sparcv9 (-KV9 が有効な場合 )

-dcc には、y または n を指定します。-dy は、リンカに対してダイナミックリンクを指示します。-dn は、リンカに対してスタティックリンクを指示します。 省略時は、-dy が適用されます。本オプションは、リンカに渡されます。

-E指定された C++ ソースファイルについて前処理だけを実行し、結果を標準出力に出力します。出力は、処理系の次の過程で使用される前処理命令を含みます。

-Gリンカに対して、ダイナミックリンク実行形式ファイルではなく、 共有オブジェクトを作成するよう指示します。本オプションは、-dn と同時には指定できません。本オプションは、リンカに渡されます。

-gfdb の使用に必要な追加情報を生成します。本オプションと -O、-Kfast、-Kfast_GP、-Kfast_GP2 または -Kfast_VI を同時に指定した場合、-O が無効になります。本オプションと同時に-Kparallelまたは PCH関連オプションを指定した場合、 -Kparallelまたは PCH 関連オプションが無効となります。

-H現在の翻訳中にインクルードされている各ファイルのパス名を、1 行ごとに標準エラー出力に出力します。

-Idir名前が / 以外で始まるインクルードファイルの検索を、dir で指定されたディレクトリを先に検索して、その後、通常のディレクトリを検索するように変更します。複数の -I オプションでディレクトリが複数指定された場合、指定された順に検索します。

二重引用符 (") で囲まれたファイルは、以下の順に検索します。1. #include 前処理指令を含む現ディレクトリ2. -I オプションで指定されたディレクトリ3. 本処理系が提供するインクルードファイルを格納するディレクトリ4. 標準のディレクトリ

角括弧 (<>) で囲まれたファイルは、以下の順に検索します。 1. -I オプションで指定されたディレクトリ 2. 本処理系が提供するインクルードファイルを格納するディレクトリ3. 標準のディレクトリ

6

第 2 章 翻訳から実行まで

インクルードファイルが絶対パス名で指定された場合、指定された絶対パス名だけ検索します。ディレクトリが存在しない場合、本オプションは無効となります。

-Ldirリンカがライブラリを検索するディレクトリのリストに、dir を加えます。本オプションは、リンカに渡されます。

-lnamelibname.so または libname.a という名前のオブジェクトライブラリをリンクします。シンボルは指定された順序にライブラリで解決されるため、コマンド行でのライブラリの指定順序が重要になります。本オプションは、ソースファイル名の後に指定してください。本オプションは、リンカに渡されます。

-mtスレッドセーフオブジェクトを生成します。ファイル名の並びに-mtを指定して翻訳されたオブジェクトプログラムが含まれているのであれば、-mt を指定する必要があります。ユーザ固有のマルチスレッドプログラムの場合、-mt を指定する必要があります。

-opathnamepathname で指定された名前のファイルを作成します。-c を同時に指定した場合、pathname の名前でオブジェクトファイルが作成されます。-G を同時に指定した場合、pathname の名前で共有オブジェクトファイルが作成されます。その他の場合、省略時設定の a.out の代わりに、pathname の名前で実行可能プログラムが作成されます。

-P指定された C++ ソースファイルに対して前処理だけを実行し、結果をサフィックス .i の付いたファイルに格納します。出力は前処理指令を含みません。

-Qcc には、y または n を指定します。-Qy の場合、 呼び出された各翻訳ツールについての識別情報が、出力ファイルに追加されます。 -Qn の場合、この情報を出力しません。省略時は、-Qy が適用されます。

-Rdir実行時に検索するライブラリのディレクトリリストに、dir を加えます。

-S指定されたソースファイルを翻訳し、アセンブラ言語出力を、サフィックス .s の付いた対応するファイルに残します。

-Uname#undef 前処理命令と同様に、name の定義を無効にします。-D オプションと -U オプションに同一の name を指定した場合は、その順序によらず、name は定義されません。

-Wtool,arg1[,arg2,...]指定された arg1[,arg2,...] をそれぞれ別の引数として tool に渡します。各引数は、直前の引数とコンマだけで区切られていなければなりません。tool には、以下のいずれかの文字を指定します。p: プリプロセッサ0: コンパイラa: アセンブラ l: リンカ

-Yitem,dir新しいディレクトリ dir を item の位置として指定します。

7

C++ 言語使用手引書

item には、以下のいずれかの文字を指定します。 0: コンパイラのパス名を dir/cpcom に変更します。a: アセンブラのパス名を dir/as 変更します。F:Fortran と言語間結合する場合、リンカが検索する Fortran ライブラリのディレクトリおよび Fortran 用スタートアップルーチンのディレクトリのパスを dir に変更します。

l: リンカのパス名を dir/ld に変更します。I: ヘッダファイルを検索するディレクトリを dir に変更します。P: 結合するライブラリのディレクトリを dir に変更します。dir には、コロンで区切ったパスリストを指定します。

r:ar のパス名を dir/ar に変更します。S: 結合するスタートアップオブジェクトファイルのディレクトリを dir に変更します。M: メッセージファイルのディレクトリを dir に指定します。

一つの item に対して複数の -Y オプションが指定された場合、 後の指定が有効となります。

--arインスタンシェートされた関数テンプレートを含む、アーカイブライブラリを生成します。同時に -opathname を指定する必要があります。pathname は、サフィックスに .a の付いた名前のファイル名でなければいけません。

2.2.2.2 メッセージ関連オプションここでは、メッセージに関するオプションについて説明します。

-j値が設定される前に使用される自動変数に関する警告を抑止します。

-V起動された各ツールについて、そのバージョン情報を標準エラー出力に出力します。

-w警告メッセージの出力を抑止します。

{--brief_diagnostics|--no_brief_diagnostics}診断メッセージを短い形式にするか否かを指示します。--brief_diagnostics を指定すると、ソース行が表示されません。--no_brief_diagnostics を指定すると、ソース行が表示されます。省略時は、--no_brief_diagnostics が適用されます。

--diag_error tag [,tag , ・・・ ]tag に指定された警告メッセージをエラーメッセージとして扱います。tag には、メッセージのエラー番号が指定できます。

--diag_suppress tag [,tag ,...]tag に指定された警告メッセージを抑止します。tag には、メッセージのエラー番号が指定できます。エラーメッセージを抑止することはできません。

--display_error_number 診断メッセージのエラーメッセージ番号を表示します。 このエラーメッセージ番号は、--diag_suppress または --diag_error の tag に指定する場合、必要となります。

--error_limit number エラーの数の限界値を number に設定します。この限界値を超えると翻訳を中断します ( ただし、警告は限界値に数えません )。省略時の限界値は、100 です。

{--for_init_diff_warning|--no_for_init_diff_warning}新しい for 初期化文の宣言のスコープで翻訳されている場合、古い仕様と動作が異なる場合に診断メッセージを出力するか否かを指示します。本オプションは、--new_for_init と同時に指定した場合に有効となります。省略時は、--for_init_diff_warning が適用されます。

8

第 2 章 翻訳から実行まで

2.2.2.3 適化関連オプションここでは、 適化機能を使用する際に指定するオプションについて説明します。

-K optopt には、以下のいずれかを指定します。a{1|2|4|8}, adr{44|64}, archi, {cfunc|nocfunc}, cpu, {dalign|nodalign}, eopt, {eval|noeval}, {FMADD|NOFMADD}, fast, fast_GP[={0|1|2}], fast_GP2[={0|1|2}], fast_VI[={0|1|2|3}], {fuse|nofuse}, GREG, {GREG_APPLI|NOGREG_APPLI}, {GREG_SYSTEM|NOGREG_SYSTEM}, {hardbarrier|nohardbarrier}, {ilfunc|noilfunc}, instance=N, {largepage[={1|2}]|nolargepage}, {lib|nolib}, {line|noline}, loopiteration_max=N, looptype={f|n|s}, {mfunc|nomfunc}, {misalign|nomisalign}, NOFLTLD, {ns|nons}, {OMP|NOOMP}, {ocl|noocl}, {PIC|pic}, pagesize=N, pagesize_heap=N, pagesize_stack=N, {parallel|noparallel}, pg, pmsg, {popt|nopopt}, {preex|nopreex}, {prefetch[={1|2|3|4}]|noprefetch}, pu, {rdconv|nordconv}, {reduction|noreduction}, SSL2, src, sta, staticlib, {unroll[=N]|nounroll}, {VIS1|VIS2|NOVIS}

-K オプションは、複数の引数の指定を受け付けます。例えば、-Klib -Kpopt の代わりに、-Klib,popt のように指定することができます。なお、-K オプションの詳細は、「2.2.2.6 -K オプション」をお読みください。

-O[n]n には、 適化レベル 0、1、2、3、4 または 5 を指定します。 適化レベルが指定されていない場合、-O3 が適用されます。 適化レベルが高いほど、実行時間が短縮されますが、翻訳時間は増加します。高位の 適化レベルは、 低位の 適化レベルを機能的に包含します。本オプションは、.s ファイルには無効です。

適化レベル 0 適化されません。-O を指定しない場合と等価です。

適化レベル 1 プログラムの流れを詳細に解析して 適化が行われます。

適化レベル 2 適化レベル 1 に加えて、以下の 適化が行われます。

・ ループ・アンローリング

オブジェクトプログラムサイズが増加する場合があります。

適化レベル 3 適化レベル 2 に加えて、以下の 適化が行われます。

・ 適化機能の繰返し実施

適化機能の繰返し実施は、 適化レベル 1 で行われる 適化機能を、 適化の余地がなくなるまで繰り返して実施します。

適化レベル 4 適化レベル 3 に加えて、以下の 適化が行われます。

・ ループ交換促進のためのループ分割

・ -KGREG_APPLI 指定時の 適化

適化レベル 5 適化レベル 4 に加えて、以下の 適化が行われます。

・ ソフトウェア・パイプライニング

・ 高度なレジスタ割当て

-x-ソースプログラム上で定義されたすべての関数に対して、関数呼出しの代わりに、インライン展開を行います。ただし、マクロ展開後の初期化のある宣言と実行文の数がインライン展開の許容値 (m) を超える関数および再帰的に呼び出される関数については、インライン展開の対象にはなりません。m の値はコンパイラが適切な値を決定します。本オプションは、-O と同時に指定した場合に有効となります。

9

C++ 言語使用手引書

本オプションと -xn を同時に指定した場合、後に指定した方が有効となります。

-xfunc1[,func2,...]ソースプログラム上で定義された関数 func1[,func2,...] に対して、関数呼出しのインライン展開を行います。 ただし、再帰的に呼び出される関数についてはインライン展開の対象にはなりません。本オプションは、-O と同時に指定した場合に有効となります。

-xn関数内の初期化のある宣言と、実行文の数が n で指定された数以下の関数に対して、インライン展開を行います。ただし、再帰的に呼び出される関数については、インライン展開の対象にはなりません。n には、0 から 2147483647 の整数値を指定します。 n が 0 のときは、インライン展開を行いません。本オプションと -x- を同時に指定した場合、後に指定した方が有効となります。-x0 が指定された場合、-x-、-xn および -xfunc1[,func2,...] は無効となり、インライン展開を行いません。本オプションは、-O と同時に指定した場合に有効となります。

2.2.2.4 言語仕様関連オプションここでは、言語仕様に関係するオプションについて説明します。

{--alternative_tokens|--no_alternative_tokens}2 文字表記および演算子キーワードを認識するか否かを指示します。--no_alternative_tokensが指定された場合、認識します。省略時は、--no_alternative_tokens が適用されます。2 文字表記は、以下のものを意味します。<% : "{" の 2 文字表記%> : " }" の 2 文字表記<: : " [" の 2 文字表記:> : " ]" の 2 文字表記%: : "#" の 2 文字表記%:%: : "##" の 2 文字表記演算子キーワードは、以下のものを意味します。and : "&&" の演算子キーワードand_eq : "&=" の演算子キーワードbitand : "&" の演算子キーワードbitor : "|" の演算子キーワードcompl : "~" の演算子キーワードnot : "!" の演算子キーワードnot_eq : "!=" の演算子キーワードor : "||" の演算子キーワードor_eq : "|=" の演算子キーワードxor : "^" の演算子キーワードxor_eq : "^=" の演算子キーワード

{--anachronisms|--no_anachronisms}言語仕様を旧仕様 (anachronisms) とみなすか否かを指示します。--anachronisms が指定された場合、みなします。省略時は、--no_anachronisms が適用されます。--strict が指定された場合、--no_anachronisms が導出されます。

{--arg_dep_lookup|--no_arg_dep_lookup}C++ において、非修飾の関数名について引数に依存した検索を行うか否かを指示します。--arg_dep_lookup が指定された場合、行います。省略時は、--arg_dep_lookup が適用されます。

{--array_new_and_delete|--no_array_new_and_delete}配列型に対する new 演算子と delete 演算子の使用を可能とするか否かを指示します。--array_new_and_delete が指定された場合、可能にします。省略時は、--array_new_and_delete が適用されます。

10

第 2 章 翻訳から実行まで

{--auto_instantiation|--no_auto_instantiation}テンプレートの自動インスタンシェーションを行うか否かを指示します。--auto_instantiation が指定された場合、行います。省略時は、--auto_instantiation が適用されます。

{--bool|--no_bool}bool をキーワードとして認識するか否かを指示します。--bool が指定された場合、認識します。省略時は、--bool が適用されます。

{--class_name_injection|--no_class_name_injection}クラス名がクラススコープに含まれるか否かを指示します(規格は含まれることを要求しています )。C++ の初期版においては、含まれないことが正しかったことがあります。--class_name_injection が指定された場合、含まれます。省略時は、--class_name_injection が適用されます。

{--const_string_literals|--no_const_string_literals}C++ の文字列および広角文字列をconstにするか否かを指示します(規格はconstであることを要求しています )。C++ の初期版においては、const でないことが正しかったことがあります。--const_string_literals が指定された場合、const にします。省略時は、--no_const_string_literals が適用されます。

{--distinct_template_signatures|--no_distinct_template_signatures}テンプレート関数の識別子が、他の翻訳単位で現れた非テンプレート関数と一致するとみなすか否かを指示します。--distinct_template_signatures が指定された場合、一致するとみなします。省略時は、--distinct_template_signatures が適用されます。

--dollar$ を識別子文字として認めるように指示します。

{--early_tiebreaker|--late_tiebreaker}型修飾子の違いなどの型互換の検出方法について、多重定義関数の解決にどのように適用されるかについて指示します。--early_tiebreaker が指定された場合、標準的なアプローチに従って、他の型互換チェックとともに、実引数の値と対応するパラメタ型の一致の正しさを調べます。--late_tiebreaker が指定された場合、 初の比較では無視されます。それは、ただ二つの関数についてすべての引数が同じ場合にだけ考慮されます。その場合、型互換の検出はどちらかを選ぶ場合に使用されます。省略時は、--early_tiebreaker が適用されます。

{--exceptions|--no_exceptions}例外処理の使用を可能にするか否かを指示します。--exceptions が指定された場合、使用を可能にします。省略時は、--exceptions が適用されます。

{--explicit|--no_explicit}explicitをキーワードとして認識するか否かを指示します。--explicitが指定された場合、キーワードとして認識します。省略時は、--explicit が適用されます。

{--extended_variadic_macros|--no_extended_variadic_macros}拡張された可変個引数マクロをサポートするか否かを指示します。 ある他のCコンパイラの可変個引数マクロへの対応をエミュレートします。--extended_variadic_macros が指定された場合、サポートします。省略時は、--no_extended_variadic_macros が適用されます。

--force_vtblFCC が、省略値でローカルに定義した仮想関数テーブルをグローバルに定義します。

{--friend_injection|--no_friend_injection}フレンド宣言だけに現れるクラス名および関数名が、通常の検索メカニズムを使用したとき、可視かどうかを指示します。--friend_injection を指定すると、可視になります。--no_friend_injection を指定すると、関数名は引数に依存した検索のときだけ可視になり、クラス名は常に見えなくなります ( 規格はこの動作を要求しています )。 省略時は、--friend_injection が適用されます。

11

C++ 言語使用手引書

{--implicit_include|--no_implicit_include}インスタンシェーションを行う場合のテンプレート実体の定義を見つける方法として、ソースファイルの暗黙の包含を行うか否かを指示します。--implicit_include が指定された場合、暗黙の包含を行います。省略時は、--no_implicit_include が適用されます。

--incl_suffixes strstr には、サフィクスリストを指定します。サフィクスの指定されていないインクルードファイルの検索を行う場合、 指定されたサフィクスを使用します。引数はコロンで分けられたリスト(h:hpp:: など ) です。サフィクスなしを許す場合は、それがサフィクスリストに含まれなければなりません。

--instantiate mode外部テンプレート実体のインスタンシェーションを制御します。外部テンプレート実体は、外部( すなわち非 inline であり、非静的な ) テンプレート関数と、テンプレートの静的データメンバです。mode には、以下のいずれかの文字を指定します。none : --no_auto_instantiation とともに指定することによって、いかなるテンプレート実体もインスタンシェートしません。 used : 翻訳時に使われるテンプレート実体をインスタンシェートします。これは、テンプレート定義のあるすべての静的データメンバを含みます。 all : 翻訳単位で宣言、または参照されたすべてのテンプレート実体をインスタンシェートします。 local: 翻訳時に使われるテンプレート実体をインスタンシェートします。それらの実体は、内部リンケージを持ちます。

--library={aCmnst}使用するライブラリを指示します。--library でライブラリを指定すると、該当するライブラリを使用するように ( または使用しないように )、適切なオプションがコンパイラおよびリンカに渡されます。a: Tools.h++,libstd,libstdm,libm の順で各ライブラリをすべて使用します。 C: libstd を使用しません。 m: libm を使用しません。 n: C++ ライブラリを使用しません。 s: libstdm を使用しません。 t: Tools.h++ を使用します。 省略時は、libstd、libstdm および libm が使用されます。

--linkfortranFortran との言語間結合で必要なライブラリの検索を行うよう指示します。本オプションを指定しない場合、この検索処理を行わないため翻訳時間を短縮することができます。

{--long_lifetime_temps|--short_lifetime_temps}一時域のライフタイムを指示します。 --long_lifetime_temps が指定された場合、スコープの終わり、switch 節、次のラベルまでの中で も近いものまでがライフタイムとなります。--short_lifetime_temps が指定された場合、完全式の終わりまでがライフタイムとなります。省略時は、--short_lifetime_temps が適用されます。

{--microsoft|--microsoft_16|--no_microsoft}マイクロソフト社拡張の認識を行うか否かを指示します。--microsoft は 32 ビットモード、--microsoft_16 は 16 ビットモードです。 マイクロソフト社拡張が認識された場合、マイクロソフト社コンパイラによって認識されない言語仕様はデフォルトでは使用できなくなります。多くの場合、これらの言語仕様は他のコマンドラインオプション (--bool など ) を使用することによって利用できます。省略時は、--no_microsoft が適用されます。

{--microsoft_bugs|--no_microsoft_bugs}マイクロソフト社コンパイラのバグの認識を指示します。これらのオプションによってMicrosoft モードになります。--microsoft_bugs が指定された場合、マイクロソフト社コンパ

12

第 2 章 翻訳から実行まで

イラのバグをエミュレートします。--no_microsoft_bugs が指定された場合、マイクロソフト社コンパイラのバグをエミュレートしません。省略時は、--microsoft_bugs が適用されます。

--microsoft_version valueMicrosoftモードにおけるエミュレートすべきマイクロソフト社コンパイラのバージョンを指示します。本オプションは特定の Microsoft モード言語仕様について利用可能かどうかを制御します。その言語仕様がマイクロソフト社コンパイラのバージョン間で変わっているためです。指定した値 (value) は、エミュレートされるマイクロソフト社コンパイラのバージョンによって、既定義マクロ _MSC_VER の値となります。例えば、1100 は Visual C++ version 5.0 に相当する値です。本オプションによって Microsoft モードになりますが、16 ビットモードまたは 32 ビットモードのどちらか一方を指定している訳ではありません。省略時の value の値は、1200 です。

{--namespaces|--no_namespaces}ネームスペースの使用を可能にするか否かを指示します。--namespaces が指定された場合、可能にします。省略時は、--namespaces が適用されます。

{--new_for_init|--old_for_init}for 初期化文の宣言のスコープを制御します。--new_for_init が指定された場合、スコープはfor 文の末尾までとします。--old_for_init が指定された場合、スコープは for 文を囲むブロックの末尾までとします。省略時は、--new_for_init が適用されます。

{--nonconst_ref_anachronism|--no_nonconst_ref_anachronism}正しい型のクラス右辺値に非constへの参照を許す旧仕様の使用を可能にするか否かを指示します。--nonconst_ref_anachronism が指定された場合、可能にします。省略時は、--nonconst_ref_anachronism が適用されます。

{--nonstd_using_decl|--no_nonstd_using_decl}C++ において、非修飾名を指定する非メンバの using 宣言を許可するか否かを指示します。--nonstd_using_decl が指定された場合、許可します。省略時は、--no_nonstd_using_decl が適用されます。

--norunpathLD_RUN_PATH を発行しません。

{--old_specializations|--no_old_specializations}旧仕様のテンプレートの限定化 (template<> を使用しない限定化 ) の使用を可能にするか否かを指示します。--old_specializations が指定された場合、可能にします。省略時は、--old_specializations が適用されます。

--pending_instantiations=Nテンプレートがインスタンシェーション処理される場合に、インスタンシェーションを行う 大値を指示します。これは、再帰的なインスタンシェーションを検出するために用いられます。Nがゼロの場合、限界はありません。省略時の N の値は、64 です。

--preinclude filename翻訳のはじめにインクルードされるファイルを指示します。 これは、標準的に使われるマクロを設定するためなどに使用できます。filename は、インクルード検索リストディレクトリ内で検索されます。

{--rtti|--no_rtti}RTTI( 実行時型情報 ) の使用を可能にするか否かを指示します。--rtti が指定された場合、dynamic_cast、typeid などの使用が可能になります。省略時は、--rtti が適用されます。

{--special_subscript_cost|--no_special_subscript_cost}オーバロード解決における、[] 演算子の整数演算項の変換に対して、特別な非標準のウェイト付けを行うか否かを指示します。--special_subscript_cost が指定された場合、行います。省略時は、--no_special_subscript_cost が適用されます。

13

C++ 言語使用手引書

--special_subscript_cost が指定された場合、以下のコードに対してエラーメッセージが出力されません。

struct A { A(); operator int *(); int operator[](unsigned);};int main(){ A a; a[0]; // 曖昧。しかし、本オプションで、 //operator[] が選択されます。}

--strict新の ISO の言語仕様で厳密に翻訳することを指示します。--strict が指定された場合、ISO

仕様以外の拡張サポートは、エラーになります。本オプションが指定された場合、--no_anachronisms が有効とみなされます。

--suppress_vtblFCC が、省略値で仮想関数テーブルを定義しなくてはならない場合、その仮想関数テーブルを定義せずに、仮想関数テーブル名を未定義のグローバル変数として出力することを指示します。

{--typename|--no_typename}typenameをキーワードとして認識するか否かを指示します。--typenameが指定された場合、キーワードとして認識します。省略時は、--typename が適用されます。

{--variadic_macros|--no_variadic_macros}可変個引数マクロをサポートするか否かを指示します。--variadic_macros が指定された場合、サポートします。省略時は、--no_variadic_macros が適用されます。

{--wchar_t_keyword|--no_wchar_t_keyword}wchar_t をキーワードとして認識するか否かを指示します。--wchar_t_keyword が指定された場合、キーワードとして認識します。省略時は、--wchar_t_keyword が適用されます。

2.2.2.5 PCH 関連オプションここでは、PCH(Pre Compiled Headers) 機能を使用する際に指定するオプションについて説明します。

--create_pch fnamefname に指定されたファイル名で PCH ファイルを作成することを指示します。 本オプションより後に、--pch または --use_pch を指定した場合、本オプションは無効となります。

--pch自動的に PCH ファイルを生成および使用することを指示します。 本オプションより後に、--use_pch または --create_pch を指定した場合、本オプションは無効となります。

--pch_dir dirdir で指定されたディレクトリに PCH ファイルを作成または検索することを指示します。本オプションは、--pch、--create_pch または --use_pch と同時に指定した場合に有効となります。

{--pch_messages|--no_pch_messages}PCH ファイルの作成、使用を示すメッセージを出力するか否かを指示します。--pch_messagesが指定された場合、メッセージを出力します。省略時は、--pch_messages が適用されます。

--use_pch fname

14

第 2 章 翻訳から実行まで

現在の翻訳対象の一部として fname で指定された PCH ファイルを使用することを指示します。本オプションより後に、--pch または --create_pch を指定した場合、本オプションは無効となります。

2.2.2.6 -K オプション

-Ka{1|2|4|8}外部変数および静的変数の 低の割り付け境界を指定します。例えば、-Ka4 を指定すると、1 から 4 バイト境界のデータを 4 バイト境界に割り付けます。省略時は、-Ka1 が適用されます。

-Kadr{44|64}絶対アドレスを 44 ビットで表すオブジェクトプログラムを生成するか、それとも 64 ビットで表すオブジェクトプログラムを生成するかを指示します。-Kadr44 が指定された場合、44 ビットで表すオブジェクトプログラムを生成します。-Kadr64 が指定された場合、64 ビットで表すオブジェクトプログラムを生成します。-Kadr44 および -Kadr64 は、-KV9 と同時に、かつ -KV9 より後に指定した場合に有効となります。

-Karchiarchi には、以下のいずれかを指定します。 詳細は、-Kcpu オプションをお読みください。

V8 SPARCV8 の命令セットを使用することを指示します。

V8PFMADD SPARCV8+ の命令セットおよび multiply add/subtract 命令を使用することを指示します。-KV8PFMADD は、-KV8PLUS および -KFMADD を同時に指定した場合と等価です。

V8PLUS SPARCV8+ の命令セットを使用することを指示します。ファイル名の並びに -KV8PLUS を指定して翻訳されたオブジェクトプログラムが含まれているのであれば、-KV8PLUS を指定する必要があります。

V9 SPARCV9 の命令セットを使用することを指示します。本オプションを指定した場合、-Kadr44 が指定されたものとみなします。ファイル名の並びに -KV9 を指定して翻訳されたオブジェクトプログラムが含まれているのであれば、-KV9 を指定する必要があります。

V9FMADD SPARCV9 の命令セットおよび multiply add/subtract 命令を使用することを指示します。-KV9FMADD は、-KV9 および -KFMADD を同時に指定した場合と等価です。

-K{cfunc|nocfunc}本処理系で用意している高速数学関数、ライブラリ関数 (malloc,calloc,realloc,free) および高速文字関数 (memcpy,memset) を利用するか否かを指示します。-Kcfunc が指定された場合、利用します。ただし、高速文字関数は、-KV8PLUS または -KV9 を同時に指定した場合に利用します。省略時は、-Knocfunc が適用されます。-Kcfunc は、-Kmfunc を機能的に包含しています。-Kcfunc と同時に -Kmfunc が指定された場合、-Kcfunc が有効となります。-Knocfunc または -Knomfunc が指定された場合、-Kcfunc および -Kmfunc が無効となります。-Kcfunc は、-mt、-KOMP または -Kparallel と同時に指定した場合、無効となります。

-Kcpucpu には、以下のいずれかを指定します。

SPARC64_GP SPARC64 GP に特有な 適化を行います。

SPARC64_GP2 SPARC64 V に特有な 適化を行います。

SPARC64VI SPARC64 VI に特有な 適化を行います。

ULTRA

15

C++ 言語使用手引書

-KULTRA1 が指定されたものとみなします。

ULTRA1 UltraSPARC-1 に特有な 適化を行います。

ULTRA2 UltraSPARC-2 に特有な 適化を行います。

「表 2.4 -Kcpu との組み合わせ」に、-Kcpu と -Karchi の指定可能な組み合わせを示します。

-K{dalign|nodalign}ポインタにより参照される double 型および long double 型のデータが、8 バイト境界にあるものとして命令を生成するか否かを指示します。-Kdalign が指定された場合、生成します。省略時は、-Knodalign が適用されます。-Kdalign を -Kmisalign と同時に指定した場合、後に指定した方が有効となります。

-Keopt演算の評価方法を変更する 適化および不変式の先行評価の 適化を行うことを指示します。本オプションを指定した場合、実行結果に副作用 ( 精度誤差および実行時の例外発生など ) が生じる場合がありますので、利用者の意図した結果にならない場合があります。本オプションは、-Keval および -Kpreex を指定したものと等価です。本オプションは、-O と同時に指定した場合に有効となります。

-K{eval|noeval}演算の評価方法を変更する 適化を行うか否かを指示します。-Keval が指定された場合、 適化を行います。省略時は、-Knoeval が適用されます。-Keval を指定した場合、実行結果に副作用 ( 精度誤差および実行時の例外発生など ) が生じる場合がありますので、利用者の意図した結果にならない場合があります。-Keval は、-O と同時に指定した場合に有効となります。-Kparallel が同時に指定されている場合、-Kreduction も有効となります。-Knoeval が指定された場合、-Kreduction も無効となります。

-K{FMADD|NOFMADD}multiply add/subtract 命令を生成するか否かを指示します。-KFMADD が指定された場合、生成します。省略時は、-KNOFMADD が適用されます。-KFMADD を指定した場合、精度が変わる場合がありますので注意が必要です。-KFMADD は、-O と -KV8PLUS または -KV9 を同時に指定した場合に有効となります。ファイル名の並びに-KFMADDを指定して翻訳されたオブジェクトプログラムが含まれているのであれば、-KFMADD を指定する必要があります。-KFMADD を指定して作成された実行形式プログラムは、SPARC64 GP、SPARC64 V および SPARC64VI 以外の機種での動作を保証しません。

-Kfast翻訳しているマシン上で、高速に実行させることを指示します。本オプションは、-O3 -Kdalign,lib,{VIS1|VIS2} -x- および -Kcpu と -Karchi のそれぞれの中から、翻訳しているマシンに合わせた 適なオプションを自動的に選択したものと等価です。本オプションと -g を同時に指定した場合、-O は無効となります。

表 2.4 -Kcpu との組み合わせ

cpu/archi V8 V8PLUS V8PFMADD V9 V9FMADD

SPARC64_GP ○ ○ ○ ○ ○

SPARC64_GP2 ○ ○ ○ ○ ○

SPARC64VI ○ ○ ○ ○ ○

ULTRA1 ○ ○ - ○ -

ULTRA2 ○ ○ - ○ -

16

第 2 章 翻訳から実行まで

-Kfast_GP[={0|1|2}]SPARC64 GP アーキテクチャ用の 適化レベルを指定します。-Kfast_GP を指定した場合、-Kfast_GP=1 が適用されます。本オプションと -g を同時に指定した場合、-O は無効となります。

-Kfast_GP=0-O5 -Kdalign,lib,SPARC64_GP,V8PLUS,VIS1 -x- を指定した場合と同様の 適化を実施します。

-Kfast_GP=1-O5 -Kdalign,lib,SPARC64_GP,V8PLUS,VIS1,FMADD -x-を指定した場合と同様の 適化を実施します。

-Kfast_GP=2-O5 -Kdalign,lib,SPARC64_GP,V8PLUS,VIS1,FMADD,eval -x- を指定した場合と同様の 適化を実施します。

-Kfast_GP2[={0|1|2}]SPARC64 V アーキテクチャ用の 適化レベルを指定します。-Kfast_GP2 を指定した場合、-Kfast_GP2=1 が適用されます。本オプションと -g を同時に指定した場合、-O は無効となります。

-Kfast_GP2=0-O5 -Kdalign,lib,SPARC64_GP2,V8PLUS,VIS1 -x-を指定した場合と同様の 適化を実施します。

-Kfast_GP2=1-O5 -Kdalign,lib,SPARC64_GP2,V8PLUS,VIS1 -x-を指定した場合と同様の 適化を実施します。

-Kfast_GP2=2-O5 -Kdalign,lib,SPARC64_GP2,V8PLUS,VIS1,eval -x-を指定した場合と同様の 適化を実施します。

-Kfast_VI[={0|1|2|3}]SPARC64 VI アーキテクチャ用の 適化レベルを指定します。-Kfast_VI を指定した場合、-Kfast_VI=1 が適用されます。本オプションと -g を同時に指定した場合、-O は無効となります。

-Kfast_VI=0-O5 -Kdalign,lib,SPARC64VI,V8PLUS,VIS2 -x- を指定した場合と同様の 適化を実施します。

-Kfast_VI=1-O5 -Kdalign,lib,SPARC64VI,V8PLUS,VIS2,FMADD -x- を指定した場合と同様の 適化を実施します。

-Kfast_VI=2-O5 -Kdalign,lib,SPARC64VI,V8PLUS,VIS2,FMADD,eval -x-を指定した場合と同様の 適化を実施します。

-Kfast_VI=3-O5 -Kdalign,lib,SPARC64VI,V8PLUS,VIS2,FMADD,eval,preex -x-を指定した場合と同様の 適化を実施します。

-K{fuse|nofuse}隣接するループを融合するか否かを指示します。-Kfuse が指定された場合、融合します。省略時は、-Knofuse が適用されます。-Kfuse は、-O(-O3 以上 ) と同時に指定した場合に有効となります。

-KGREG翻訳の段階で、g2 から g6(-KV9 指定時は g2、g3、g6) のグローバル・レジスタをレジスタ割付けの対象にする 適化を行うことを指示します。本オプションは、-KGREG_APPLI,GREG_SYSTEM を指定した場合と等価です。

-K{GREG_APPLI|NOGREG_APPLI}翻訳の段階で、g2 から g4(-KV9 指定時は g2、g3) のグローバル・レジスタをレジスタ割付けの対象にする 適化を行うか否かを指示します。これらのレジスタは、アプリケーションプログラムに使用します。-KGREG_APPLI を指定すると、レジスタ割付けの対象にします。省略時は、-KNOGREG_APPLI が適用されます。

17

C++ 言語使用手引書

-KNOGREG_APPLI は、-O4 または -O5 と同時に指定された場合、無効となります。

-K{GREG_SYSTEM|NOGREG_SYSTEM}翻訳の段階で、g5、g6(-KV9 指定時は g6) のグローバル・レジスタをレジスタ割付けの対象にする 適化を行うか否かを指示します。これらのレジスタは、システムで予約されたレジスタです。-KGREG_SYSTEM を指定すると、レジスタ割付けの対象にします。省略時は、-KNOGREG_SYSTEMが適用されます。-KGREG_SYSTEM は、-O と同時に指定した場合に有効となります。-KGREG_SYSTEM は -mt、-KOMP または -Kparallel と同時に指定した場合、無効となります。

-K{hardbarrier|nohardbarrier}スレッド間ハードウェアバリア機能を使用する実行可能プログラムを作成するか否かを指示します。-Khardbarrierが指定された場合、作成します。省略時は、-Knohardbarrierが適用されます。-Khardbarrier は、-Kparallel または -KOMP と同時に指定した場合に有効となります。本機能は、Parallelnavi 固有機能です。スレッド間ハードウェアバリア機能については、「付録C Parallelnavi」をお読みください。

-K{ilfunc|noilfunc}単精度および倍精度型の数学関数 sin、cos、log10、log および exp をインライン展開するか否かを指示します。-Kilfunc が指定された場合、インライン展開します。省略時は、-Knoilfuncが適用されます。-Kilfunc を指定した場合、精度差が発生する場合がありますので注意が必要です。-Kilfunc を指定した場合、-Klib が指定されたものとみなされます。-Knoilfunc または -Knolib が指定された場合、-Kilfunc および -Klib が無効となります。-Kilfunc は、-O および -Klib と同時に指定した場合に有効となります。

-Kinstance=N実行時のスレッド数 Nを指定します。N は、2 から 128 の整数値です。本オプションは、-Kparallel と同時に指定した場合に有効となります。

-K{largepage[={1|2}]|nolargepage}ラージページ機能を使用する実行可能プログラムを作成するか否かを指示します。-Klargepageが指定された場合、作成します。省略時は、-Knolargepage が適用されます。-Klargepage だけが指定された場合、-Klargepage=1 が適用されます。本機能は、Parallelnavi 固有機能です。ラージページ機能については、「付録 C Parallelnavi」をお読みください。

-Klargepage=1データ域およびヒープ域に対してラージページ機能を適用します。

-Klargepage=2データ域およびヒープ域に加えて、スタック域に対してもラージページ機能を適用します。

-K{lib|nolib}標準関数の動作を認識して、標準関数のインライン展開および同じ動作をするより高速な標準関数に置き換える 適化を行うか否かを指示します。-Klib が指定された場合、 適化を行います。省略時は、-Knolib が適用されます。標準関数と同名の利用者が定義した関数を使用している場合、-Klib を指定すると利用者の意図した結果にならない場合があります。-Klib は、-O と同時に指定した場合に有効となります。

-K{line|noline}プログラミング支援ツール (Parallelnavi 環境 )、あるいは並列アナライザ ( 非 Parallelnavi環境)で提供される実行時間のサンプリング機能に必要な追加情報を生成するか否かを指示します。-Kline が指定された場合、生成します。省略時は、-Knoline が適用されます。

-Kloopiteration_max=Nループの繰り返し回数の 大値 N を指定します。N は、1 から 2147483647 の整数値です。本オプションは、-Kparallel と同時に指定した場合に有効となります。

-Klooptype={f|n|s}

18

第 2 章 翻訳から実行まで

ループの継続条件および方向を指定します。省略時は、-Klooptype=f が適用されます。

-Klooptype=f継続条件が常に真となるループはないが、逆向きループが含まれる可能性があることを指示します。

-Klooptype=n継続条件が常に真となるループおよび逆向きループが含まれる可能性があることを指示します。

-Klooptype=s継続条件が常に真となるループおよび逆向きループがないことを指示します。

-K{mfunc|nomfunc}本処理系で用意している高速な数学関数を利用するか否かを指示します。-Kmfunc が指定された場合、利用します。省略時は、-Knomfunc が適用されます。

-K{misalign|nomisalign}ポインタにより参照されるデータがどのような境界の領域に割り付けられているか不明なものとして、命令を生成するか否かを指示します。-Kmisalign が指定された場合、命令を生成します。省略時は、-Knomisalign が適用されます。-Kmisalign を -Kdalign と同時に指定した場合、後に指定した方が有効となります。-Kmisalign は、-O(-O5 を除く ) と同時に指定した場合に有効となります。-Kmisalign は、-O5、-Kfast_GP、-Kfast_GP2 または -Kfast_VI と同時に指定した場合、無効となります。

-KNOFLTLDnon-faulting load を生成することを指示します。non-faulting load は与えられたアドレスが不当なものであっても例外を発生しません。この命令を利用することで、メモリへのアクセスを、そのアドレスが正当なものかどうかを判定する前に実行することができます。本オプションは、-O と -KV8PLUS または -KV9 を同時に指定した場合に有効となります。

-K{ns|nons}FPU を non-standard floating point mode で初期化するか否かを指示します。 -Kns が指定された場合、初期化します。省略時は、 -Knons が適用されます。-Kns を指定した場合、高速な性能を得るために、アンダフローの数値をゼロにすることがあります。-Kns は、-O と同時に指定した場合に有効となります。

-K{OMP|NOOMP}OpenMP 仕様を受け入れるか否かを指示します。-KOMP が指定された場合、受け入れます。省略時は、-KNOOMP が適用されます。-KOMP が指定された場合、-mt が指定されたものとみなされます。ファイル名の並びに-KOMPを指定して翻訳されたオブジェクトプログラムが含まれているのであれば、-KOMP を指定する必要があります。

-K{ocl|noocl}適化制御行 (OCL) を有効にするか否かを指示します。-Kocl が指定された場合、有効にします。

省略時は、-Kocl が適用されます。

-K{PIC|pic}位置独立コード (PIC) を生成することを指示します。-KPIC と -Kpic を同時に指定した場合、後に指定した方が有効になります。

-Kpagesize=N本オプションは、-Kpagesize_heap=N および -Kpagesize_stack=N を指定した場合と等価です。

-Kpagesize_heap=Nヒープ域のページサイズを設定します。N は、8K、64K、512K、4M、32M、256M、2G または 16G です。なお、2G または 16G は、-KV9 が有効な場合に意味があります。

19

C++ 言語使用手引書

N には、システムがサポートしている有効なページサイズを指定してください。有効なページサイズは、pagesize(1M) コマンドの -a オプションを使って確認することができます。有効なページサイズを指定しなかった場合は、実行時に以下のメッセージが出力され、その要求は無視されます。SIZE は、-Kpagesize_heap または -Kpagesize に指定した値です。 fjmpss runtime:The heap page size(SIZE) specified by -Kpagesize_heap or -Kpagesize cannot be used in this system.本オプションは、-Klargepage と同時に指定できません。本オプションは、翻訳時およびリンク時に指定する必要があります。本オプションは、Solaris 9 以降の場合に有効です。本オプションを指定すると、オペレーティングシステムにインストールされた MPSS(MultiplePage Size Support) 機能が、ヒープ域に任意のページサイズを割り当てます。MPSS 機能の詳細については、Solaris マニュアルをお読みください。

-Kpagesize_stack=Nスタック域のページサイズを設定します。N は、8K、64K、512K、4M、32M、256M、2G または 16G です。なお、2G または 16G は、-KV9 が有効な場合に意味があります。N には、システムがサポートしている有効なページサイズを指定してください。有効なページサイズは、pagesize(1M) コマンドの -a オプションを使って確認することができます。有効なページサイズを指定しなかった場合は、実行時に以下のメッセージが出力され、その要求は無視されます。SIZE は、-Kpagesize_stack または -Kpagesize に指定した値です。 fjmpss runtime:The stack page size(SIZE) specified by -Kpagesize_stack or -Kpagesize cannot be used in this system.本オプションは、-Klargepage と同時に指定できません。本オプションは、翻訳時およびリンク時に指定する必要があります。本オプションは、Solaris 9 以降の場合に有効です。本オプションを指定すると、オペレーティングシステムにインストールされた MPSS(MultiplePage Size Support) 機能が、スタック域に任意のページサイズを割り当てます。MPSS 機能の詳細については、Solaris マニュアルをお読みください。

-K{parallel|noparallel}自動並列化機能を利用するか否かを指示します。-Kparallel が指定された場合、利用します。省略時は、-Knoparallel が適用されます。-Kparallel を指定した場合、-O3 -mt -Klooptype=f が指定されたものとみなされます (-O0、-O1または -O2 を指定しても無効になります )。-Kparallel は、-g と同時に指定した場合、無効となります。ファイル名の並びに -Kparallel を指定して翻訳されたオブジェクトプログラムが含まれているのであれば、-Kparallel を指定する必要があります。

-Kpg適化を行うために、コンパイラが参照するプロファイル情報を生成するための命令列を生成す

ることを指示します。 本オプションは、-O と同時に指定した場合に有効となります。本オプションは、-KOMP と同時に指定した場合、無効となります。

-Kpmsg並列化の状況をメッセージとして出力することを指示します。本オプションは、-Kparallel と同時に指定した場合に有効となります。

-K{popt|nopopt}ポインタにより参照される領域は、そのポインタでだけ参照されるものと限定解釈して、ポインタにより指されるデータの 適化を行うか否かを指示します。-Kpopt が指定された場合、 適化を行います。省略時は、-Knopopt が適用されます。-Kpopt を指定し、同じ領域を複数のポインタで参照している場合、またはポインタによる参照とポインタによらない参照が混在している場合、利用者の意図した結果にならない場合があります。-Kpopt は、-O と同時に指定した場合に有効となります。

-K{preex|nopreex}

20

第 2 章 翻訳から実行まで

不変式の先行評価の 適化を行うか否かを指示します。-Kpreex が指定された場合、 適化を行います。省略時は、-Knopreex が適用されます。この 適化は、実行結果に副作用をおよぼす可能性がありますので、利用者の意図した結果にならない場合があります。-Kpreex は、 -O と同時に指定した場合に有効となります。

-K{prefetch[={1|2|3|4}]|noprefetch}prefetch 命令を使用したオブジェクトプログラムを生成するか否かを指示します。-Kprefetchが指定された場合、生成します。省略時は、-Knoprefetch が適用されます。-Kprefetch( レベル指定なし ) を指定した場合、-Kprefetch=2 が適用されます。-Kprefetch は、-O と -KV8PLUS または -KV9 を同時に指定した場合に有効となります。

-Kprefetch=1ループ内で使用される配列データに対して、ループ内に prefetch 命令を生成します。ただし、多重ループの場合は、 内ループ内の配列データのみ対象とします。

-Kprefetch=2-Kprefetch=1 に加えて、キャッシュのラインサイズよりも大きなストライドでアクセスされる配列データを対象とします。

-Kprefetch=3-Kprefetch=2 に加えて、プリフェッチするアドレスが翻訳時に確定しないループにおいて、アドレス計算するための命令を生成してプリフェッチすることを指示します。

-Kprefetch=4-Kprefetch=3 に加えて、添字が複雑な場合でも連続アクセスとみなして積極的にプリフェッチすることを指示します。

-Kpu-Kpg の指定によって得たプログラム実行時のプロファイル情報を使用した 適化を行うことを指示します。CPU 数や 大のスレッド数は、-Kpg を指定して作成したプログラムの実行時と同じでなければなりません。本オプションは、-O と同時に指定した場合に有効となります。

-K{rdconv|nordconv}型変換命令をループの外に移動する 適化を行うか否かを指示します。-Krdconv が指定された場合、 適化を行います。省略時は、-Knordconv が適用されます。符号付き整数の加減算がオーバフローする場合、-Krdconv を指定したときと指定しないときとで結果が異なることがあります。-Krdconv は、-O(-O3 以上 ) と同時に指定した場合に有効となります。

-K{reduction|noreduction}リダクションの 適化を行うか否かを指示します。-Kreduction が指定された場合、 適化を行います。省略時は、-Knoreduction が適用されます。-Kreduction は、-Kparallel と同時に指定した場合に有効となります。リダクション 適化の詳細は、「第 4 章 並列化機能」をお読みください。

-KSSL2C-SSL Ⅱおよび BLAS/LAPACK を利用することを指示します。リンク時に C-SSL Ⅱライブラリが結合されます。

-Ksrcソースリストを出力することを指示します。OpenMP仕様のディレクティブによって並列化などを指示された文についての出力は、「第4章 並列化機能」をお読みください。

-Ksta統計情報を出力することを指示します。

-Kstaticlib本処理系が提供するライブラリを静的結合することを指示します。

21

C++ 言語使用手引書

本オプションは、リンク時に指定する必要があります。

-K{unroll[=N]|nounroll}ループ展開により展開するか否かを指示します。-Kunroll が指定された場合、展開します。-O0または -O1 が有効な場合、省略時は、-Knounroll が適用されます。-O2 以上が有効な場合、省略時は、-Kunroll が適用されます。-Kunroll[=N] が有効な場合、ループ展開数の上限 N を指定します。N は、2 から 100 までの整数値です。N の指定を省略した場合、コンパイラが自動的に 適な値を決定します。-Kunroll は、-O と同時に指定した場合に有効となります。

-K{VIS1|VIS2|NOVIS}VIS(Visual Instruction Set)バージョン1.0または2.0を出力するか否かを指示します。-KVIS1が指定された場合、バージョン 1.0 を出力します。-KVIS2 が指定された場合、バージョン 2.0を出力します。省略時は、-KNOVIS が適用されます。-KVIS1 または -KVIS2 は、-KV8PLUS または -KV9 と同時に指定した場合に有効となります。ファイル名の並びに-KVIS1または-KVIS2を指定して翻訳されたオブジェクトプログラムが含まれているのであれば、-KVIS1 または -KVIS2 を指定する必要があります。

2.2.3 翻訳時オプションの注意事項翻訳時オプションで注意すべき点について説明します。

■ -K オプションの複数指定-K オプションは、その後ろにコンマ (,) で区切って複数のオプションを続けて指定することができます。また、複数の -K オプションに分けて指定することもできます。 以下の例では、二つのコマンドは同じオプションが指定されたものとみなします。

例 )$ FCC -o pgm.out -Kunroll -Kpreex -Keval pgm.cc$ FCC -o pgm.out -Kunroll,preex,eval pgm.cc

■空白の禁止-K オプションに続いて指定するオプションには、空白を含むことはできません。 以下の例では、"unroll" の前に空白があるため、"unroll" は無効となります。

例 )誤った指定$ FCC -O -Kpreex, unroll pgm.cc

正しい指定$ FCC -O -Kpreex,unroll pgm.cc

■ 64 ビットで動作する実行可能プログラム翻訳時オプション -KV9 を指定することにより、64 ビットで動作する実行可能プログラムを作成することができます。以下の注意が必要です。

・ -KV9 を指定して翻訳したオブジェクトプログラムは、-KV9 を指定して結合編集してください。また、-KV9 を指定して翻訳されていないオブジェクトプログラムは、-KV9 を指定して結合編集できません。

・ Solaris 8 OS 以降で翻訳および結合編集ができます。

・ 64 ビット Solaris OS 上だけで実行することができます。

例 ) 64 ビットで動作する実行可能プログラムの作成例$ FCC a.cc -KV9または、$ FCC a.cc -KV9 -c$ FCC a.o -KV9

■ -Karchi または -Kcpu-Kfast、-Kfast_GP、-Kfast_GP2 または -Kfast_VI より前に -Karchi -Kcpu オプションを指定した場合、指定した -Karchi -Kcpu が無効となります。(-Kfast、-Kfast_GP、-Kfast_GP2 または-Kfast_VI から導かれる -Karchi -Kcpu が有効となります。)-Karchi -Kcpu は、-Kfast、-Kfast_GP、-Kfast_GP2 または -Kfast_VI の後に指定してください。

22

第 2 章 翻訳から実行まで

■ -dn または -Bstatic-dn または -Bstatic と同時に、-KV9、-KOMP、-Kparallel、-Klargepage、-Khardbarrier または-mt を指定することはできません。Solaris 10 OS のシステムでは、-dn および -Bstatic を指定することはできません。スタティックライブラリが提供されていないため、リンク時にエラーとなります。

■ -g以下の条件のソースプログラムを、-g を指定し翻訳した場合、リンク時にエラーとなります。1) 内部リンケージを持つ関数定義がある。かつ、2)1) の関数から関数定義のない関数を呼び出している。

■標準ヘッダファイルについて本処理系で提供している標準ヘッダファイルを取り込み、以下の翻訳時オプションを指定して翻訳すると、翻訳時エラーとなります。標準ヘッダファイルを使用する際は、以下の翻訳時オプションを指定しないでください。・ --no_array_new_and_delete・ --no_bool・ --no_distinct_template_signatures・ --no_explicit・ --instantiate all・ --no_namespaces・ --no_old_specializations・ --no_typename・ --no_wchar_t_keyword

■ 2G バイトを超えるファイルの利用32ビットアドレスモードの実行可能プログラムで2Gバイトを超えるファイルを利用したい場合、以下の翻訳時オプションを指定してください。 -D_FILE_OFFSET_BITS=64

2.3 翻訳時プロフィルファイル

翻訳時プロフィルファイル (/etc/opt/FSUNfccpp/FCC_PROF) を設定することにより、翻訳時オプションのデフォルトを変更することができます。翻訳時プロフィルファイルは、以下の形式に従って作成してください。

・ 二重引用符 (") または一重引用符 (') で囲まれていない空白文字は、意味を持ちません。

・ 文字列の開始および終了を表す二重引用符および一重引用符は、すべて等価です。ただし、一連の文字列は、必ず開始を表す二重引用符および一重引用符と同一の文字または行末によって終了します。

・ 文字列に含まれていない "#" から行末までは、コメントと解釈します。

以下に、翻訳時プロフィルファイルの指定例を示します。

例 ) #Default options-w -O

翻訳時オプションの指定の優先順位は、以下のように決定されます。1) 翻訳コマンドのオペランド2) 環境変数 (FCC_ENV)3) プロフィルファイル4) 標準値

2.4 実行の手続き

ここでは、プログラムを実行するための手続きについて説明します。

23

C++ 言語使用手引書

2.4.1 実行時環境変数実行時オプションは、環境変数に指定します。実行時環境変数は、並列化機能 (「第 4 章並列化機能」参照 ) を使用時に有効になります。「表 2.5 実行時環境変数」に、実行時に指定できる環境変数を示します。なお、OpenMP仕様の環境変数については、「4.3.1.2.2 OpenMP仕様の環境変数」をお読みください。

2.4.2 実行時オプションの指定方法setenv コマンドを用いて、環境変数に実行時オプションを設定します。

例 ) $ setenv MPCL trace$ a.out

2.4.3 実行時の注意事項本処理系で作成されたプログラムを実行する場合の注意事項を、以下に示します。

■実行時の変数割付け 本処理系で作成されたプログラムは、手続き内でローカルな変数およびプライベート変数をスタック領域に割り付けます。手続き内でローカルな変数およびプライベート変数に必要な領域が巨大な場合には、スタック領域を十分な大きさに拡張する必要があります。プロセスのスタック領域は、limit(1) コマンドで設定できます。

表 2.5 実行時環境変数

環境変数名 オペランド 意味

FLIB_C_MESSAGE なし 環境変数が存在する場合、ユーザプログラムの実行時にエラーが発生した場合にエラーメッセージを標準エラー出力へ出力します。

FLIB_SPINWAIT unlimited,0,<n>sまたは<n>ms

並列処理を行う場合に、同期待ち処理を調節することができます。詳細は、「4.2.1.2.5 同期待ち処理」および「4.3.1.2.1 実行時の環境変数」をお読みください。

FLIB_FASTOMP TRUE OpenMP による並列処理を行う場合に、高速実行時ライブラリを使用することができます。詳細は、「4.3.1.2.1 実行時の環境変数」をお読みください。

FLIB_NOHARDBARRIER

なし 本機能は、Parallelnavi 固有機能です。詳細は、「付録C Parallelnavi」をお読みください。

FLIB_HARDBARRIER_MESSAGE

なし 本機能は、Parallelnavi 固有機能です。詳細は、「付録C Parallelnavi」をお読みください。

FLIB_PARALLEL_INFO

1 または 2 並列実行情報を出力することができます。詳細は、「4.3.6並列実行情報」をお読みください。

MPCL trace ユーザプログラムの実行時にエラーが発生した場合にエラートレース情報を標準エラー出力へ出力します。

PARALLEL n 自動並列で使用されるスレッドの 大数を指定します。n は使用可能なスレッド数で、1~ 2147483647 の整数値です。

THREAD_STACK_SIZE n スレッド毎のスタック領域の大きさを K バイト単位で指定することができます。詳細は、「2.4.3 実行時の注意事項」をお読みください。n は使用可能なスレッド数で、32 ビットプログラムの場合、1~ 2147483647 の整数値、64 ビットプログラムの場合、1 ~ 18446744073709551615 の整数値です。

24

第 2 章 翻訳から実行まで

25

C++ 言語使用手引書

26

第 3章 逐次 適化機能

本章では、逐次 適化機能の概要および有効に活用する方法について説明します。

3.1 適化の概要

適化の目的は、プログラムを可能な限り高速に実行できるようなオブジェクトプログラム(命令列およびデータ域)を生成することです。 適化機能を使用することにより、プログラムの実行時間を短縮することができます。コンパイラの 適化機能は、C++ ソースプログラムからオブジェクトプログラムを生成する過程で、以下に示すことを行います。

削除

同じ結果をもたらす文や式がある場合、無駄な部分を削除します。また、実行しても意味がない文や式があれば、それらも削除します。

移動

繰り返し実行する部分(ループと呼ばれる)に、何回繰り返しても同じ結果になる文や式があれば、それらをループの外側に移動します。また、繰り返して実行しなくても 終的な結果が分かる場合は、必要な部分だけをループの中に残し、他の部分はループの外側に移動します。

変更

演算式の演算子を、計算誤差が生じない範囲で変更することがあります。また、演算の対象になるデータも変更することがあります。たとえば、一度だけ定数が代入されて、それ以後は値が変わらない変数の引用がある場合、その変数の引用は定数の引用に変更します。

展開

ライブラリ関数や利用者定義の関数を引用(呼び出し)している場合、可能であれば関数の本体が引用しているところに展開します。引数や関数値の受け渡しおよび呼び出しや復帰のための命令列が不要になるので、実行時間が短縮されます。

実行

文の実行結果や式の演算結果が翻訳時に分かる場合、文の実行や式を計算する命令列は出力せずに、翻訳時に実行または計算した結果を使用します。

その他

ハードウェアの機能・特徴(命令の種類、レジスタの種類と個数、アドレッシング方法など)を大限に利用して高速に実行できる命令列およびデータ域を出力します。

適化機能を使用することによって実行時間を短縮することができます。しかし、翻訳時間と翻訳作業域は増加します。また、 適化の内容によっては、オブジェクトプログラムの大きさが大

幅に増加したり、実行結果に副作用を及ぼす可能性がある 適化もあります注。このため、 適化機能を使用するかどうかは、翻訳時オプションにより選択できるようになっています。

3.2 標準 適化

適化レベル 1(-O1) から 適化レベル 5(-O5)が指定されると、標準 適化が実施されます。標準 適化の代表的な機能について説明します。

3.2.1 共通式の除去等しい演算結果をもたらす二つの式(共通式)が存在する場合、後の式では演算せずに前の式の演算結果を利用します。共通式の除去の対象となるのは、算術演算、関係演算、論理演算および一部のライブラリ関数の引用です。

注 .実行結果に副作用を及ぼす可能性がある 適化機能項目は、利用者が翻訳時オプションで指定しない限り実施されないので、通常の使用で副作用が発生することはありません。

27

C++ 言語使用手引書

以下に、共通式の除去の例を示します。

例 : 共通式の除去

[ 説明 ]代入式の右辺の一部である x*y が共通式です。2 度目の計算を除去して 初の計算結果 t を使用するように変更します。t はコンパイラが生成した変数です。

3.2.2 不変式の移動ループ内で値が変化しない式(不変式)を、ループの外側に移動します。不変式の移動の対象となるのは、算術演算、関係演算、論理演算および一部のライブラリ関数の引用です。以下に、不変式の移動の例を示します。

例 : 不変式の移動

[ 説明 ]文全体の y = a[j]*2; および式の一部の y*z をループ外に移動します。t はコンパイラが生成した変数です。

この 適化により移動するのは、通常はループ内で必ず実行される文の一部または全体です。ただし、-Kpreex を指定した場合は、判定文などにより、ループ内で選択的に実行される文に含まれる不変式も移動します。この 適化を、通常の不変式の移動とは区別して、不変式の先行評価と呼びます。不変式の先行評価を実施することにより、より実行時間を短縮することができます。しかし、移動による副作用が生じることがあるので注意が必要です。不変式の先行評価による副作用については、「3.3.2.1 不変式の先行評価」 をお読みください。

3.2.3 演算子の強さの縮小演算子の強さとは、演算に要する実行時間の相対的な大小関係をいいます。強い演算子ほど実行時間を多く必要とします。一般に、加算と減算の強さは同じです。乗算は加減算よりも強く、除算は乗算よりも強くなります。また、整数型と浮動小数点型の間の型変換は、加減算よりも強く乗算より弱くなります。演算子の強さの縮小とは、" 乗算は加減算に " というように、演算子の強さをより弱い方向に変更することにより、実行時間を短縮する 適化のことです。

この 適化は、ループ内で値が階段状に規則的に変化する整数型の変数注 と、その変数を引用している式を対象に、加減算への縮小を行います。以下に、強さの縮小の例を示します。

注 .このような性質を持つ変数を誘導変数と呼びます。このため、演算子の強さの縮小は、誘導変数の 適化とも呼びます。

a = x * y + c;......

b = x * y + d;

t = x * y;a = t + c;

...b = t + d;

for(i=0; i<n; i++){ y = a[j] * 2; x = x + y * z;}

y = a[j] * 2;t = y * z;for(i=0; i<n; i++){

x = x + t;}

28

第 3 章 逐次 適化機能

例 1: 演算子の強さの縮小(乗算から加算への縮小)

[ 説明 ]誘導変数 i に対する演算 i*100 に対して 適化を行い、ループ内の演算 i*100 を加算 t=t+100に変換します。t はコンパイラが生成した変数です。

例 2: 演算子の強さの縮小(型変換から加算への縮小)

[ 説明 ]誘導変数 i に対する演算 (float)i に対して 適化を行い、整数型から浮動小数点型への型変換を、浮動小数点型の加算 t=t+1.0 に変換します。t はコンパイラが生成した浮動小数点型の変数です。

3.2.4 ループ・アンローリングループ・アンローリングとは、ループ内のすべての実行文をループ内に n 重に展開し、その代わりループの回転数を n分の 1 に縮小する 適化です。ループ外からの飛び込みがないループに対して行われます。展開数 n は、ループの回転数、ループ内の実行文の数と種類、および使われているデータの型などから、コンパイラにより 適な値が決められます。また、 適化制御行 (OCL) により、ソースプログラム上に展開数を指定することもできます。この機能については、「3.4.1 適化制御行(OCL) の利用」をお読みください。回転数が縮小され、かつ、多重に展開された実行文がループ内で一体になって 適化されるので、高速なオブジェクトプログラムが得られます。ただし、ループ内の実行文が多重に展開されるので、オブジェクトプログラムの大きさが増加します。ループ・アンローリングは、 適化レベル 2(-O2)以上の場合に行われます。また、-Knounrollを指定することにより、抑止することができます。以下に、ループ・アンローリングの例を示します。

例:ループ・アンローリング

...for(i=1; i<10; i++){

... j = k + i * 100;

...}

t = 100;for(i=1; i<10; i++){

... j = k + t;

... t = t + 100;}

...for(i=1; i<10; i++){

... x = (float)i;

...}

t = 1.0;for(i=1; i<10; i++){

... x = t;

... t = t + 1.0;}

int i, j, k;float a[400][400], b[400][400], c[400][400];for(i=0; i<400; i++) for(j=0; j<400; j++){ c[i][j] = 0.0; for(k=0; k<400; k++) c[i][j] += a[i][k] * b[k][j]; }

29

C++ 言語使用手引書

たとえば、展開数が 4 の場合、オブジェクトプログラムを生成する過程で、 も内側のループが以下のように変形されます。

3.2.5 ソフトウェア・パイプライニングソフトウェア・パイプライニングとは、命令レベルの並列化が可能なマシンにおいて、ループ内の命令ができるだけ並列実行されるように命令を並び替える 適化です。ソフトウェア・パイプライニングは、ループの任意の回転における実行文と、それ以降の回転における実行文を重ね合わせた命令スケジューリングを行います。このため、ループ・アンローリングと同様、オブジェクトモジュールの大きさが増加します。ソフトウェア・パイプライニングは、 適化レベル 5(-O5) が指定された場合に行われます。

3.3 拡張 適化

拡張 適化機能のオプションが指定されると、標準 適化に加えて、拡張 適化が実施されます。ここでは、拡張 適化の代表的な機能について説明します。拡張 適化の機能項目によっては、コンパイラが出力するオブジェクトプログラム(命令列およびデータ域)の大きさが大幅に増加したり、実行結果に副作用が生じることがあるので、注意が必要です。

3.3.1 インライン展開インライン展開とは、関数の引用(呼び出し)がある場合に、その引用箇所に関数の本体を直接展開する 適化です。展開することによって、引数や関数値の受け渡しおよび呼び出しと復帰のためのオーバヘッド(レジスタの退避・復元と分岐)が削除されます。また、展開された部分が呼び出し元と一体化されるので、他の 適化が促進されます。したがって、実行時間を大幅に短縮することができますが、オブジェクトプログラムの大きさが増加します。

標準関数のインライン展開

標準関数の動作を認識して、標準関数のインライン展開および同じ動作をする、より高速な標準関数への置き換えを行います。このため、標準関数と同じ名前の関数を利用者が定義している場合は、利用者の意図した結果にならない場合があります。標準関数のインライン展開は、-Klib オプションで制御することができます。

ソース上で定義された関数のインライン展開

C++ ソースプログラム上で定義されたすべての関数に対して、関数呼び出しのインライン展開を行います。C++ ソースプログラム上で定義された関数のインライン展開は、-x オプションで制御することができます。

3.3.2 評価方法を変更する 適化不変式の先行評価および演算評価方法の変更による 適化について説明します。

3.3.2.1 不変式の先行評価if 文などにより、ループ内で選択的に実行される文に含まれる不変式を、ループの外側に移動します。不変式の先行評価を実施することにより、より実行時間を短縮できますが、移動により副作用が生じることがあるので注意が必要です。不変式の先行評価は、-Kpreex オプションで制御することができます。

for(k=0; k<400; k+=4){ c[i][j] += a[i][k ] * b[k ][j]; c[i][j] += a[i][k+1] * b[k+1][j]; c[i][j] += a[i][k+2] * b[k+2][j]; c[i][j] += a[i][k+3] * b[k+3][j]; }

30

第 3 章 逐次 適化機能

不変式の先行評価により、プログラムの論理上実行されないはずの命令が実行され、エラーになる場合があります。ただし、計算結果およびその精度に影響を与えることはありません。実行場所の移動による影響は、ライブラリ関数の引用、配列要素の引用および除算で発生する可能性があります。以下に、不変式の先行評価による影響の例を示します。

例 1: 配列要素の引用

[ 説明 ]左側のプログラムでは、変数 j が 9 以下のときだけ配列要素 b[j] を引用しているので、配列b の宣言範囲を超えることはありません。不変式の先行評価により、配列要素 b[j] がループ外に移動されて、j の値に関係なく引用されます。その結果、たとえば jの値が10 以上であれば、配列の宣言範囲を超えて引用されます。j の値が非常に大きい場合は、不当な領域を参照して、プログラムの実行が中断することがあります。t はコンパイラが生成した int 型の変数です。

例 2:除算

[ 説明 ]左側のファイルでは、変数 f が 0 でないときだけ除算を行っているので、除算例外のエラーが発生することはありません。不変式の先行評価により、除算 b/f がループ外に移動されて、f の値に関係なく実行されます。その結果、たとえば変数 f の値が 0 であれば、プログラムの実行が中断します。t はコンパイラが生成した int 型の変数です。

3.3.2.2 演算評価方法の変更演算の評価方法を変更して実行時間を短縮します。変更により副作用が生じることがあるので注意が必要です。

演算順序の変更

定数どうしの翻訳時計算、不変式の移動、命令スケジューリングなどの 適化を促進するため、演算順序を変更します。演算例外(オーバフローやアンダフロー)が発生しなかった計算が、演算順序を変更することによって演算例外が発生する場合があります。また、浮動小数点演算では、各演算項の有効桁によっては、演算結果の精度が異なる場合があります。演算順序の変更は、-Keval オプションで制御することができます。以下に、演算順序の変更の例を示します。

int a[10], b[10];...

for(i=0; i<10; i++){ if(j<10) a[i] = b[j] * f;}

...

int a[10], b[10];...

t = b[j] * f;for(i=0; i<10; i++){ if(j<10) a[i] = t;}

...

int a[100],b,f;...

for(i=0; i<n; i++){ if(f != 0) a[i] = b / f; else a[i] = 0;}

...

int a[100],b,f;...

t = b/f;for(i=0; i<n; i++){ if(f != 0) a[i] = t; else a[i] = 0;}

...

31

C++ 言語使用手引書

例:演算順序の変更

[ 説明 ]不変項どうしの演算が集められた後、x*y が不変式としてループの外側に移動されます。配列 b,c および変数 x,y の値によっては、左側の計算では演算例外が発生せず意図したとおり計算できたものが、右側の計算では演算例外が発生し意図した結果が得られない場合があります。t はコンパイラが生成した double 型の変数です。なお、演算順序の変更により演算例外が発生したり演算結果の精度が異なるようなプログラムは、もともと限界値に近い値を処理したり精度に敏感な計算をしているプログラムであるともいえます。したがって、本 適化を実施して副作用が発生したとしても、本 適化が根本的な原因ではない場合もあります。

除算の乗算化

ループ内で不変な除算を乗算に変更します。この除算の乗算化により、実行速度を短縮することができますが、実行結果の精度に影響を与える場合があるので注意が必要です。除算の乗算化は、-Keval オプションで制御することができます。以下に、除算の乗算化の例およびその影響を示します。

例:除算の乗算化

[ 説明 ]ループ内の演算 b[i]/v を乗算 b[i]*t に変換します。t はコンパイラが生成した float 型の変数です。右側のプログラムでは、 適化により 1.0/v がループの外に移動されて t の乗算に変更され、精度誤差が生じる可能性があります。

3.3.3 ポインタの 適化ポインタの 適化を行わない場合 ( 通常 ) は、ポインタ変数がどこを指しているかわからないという前提のもとに、安全側に立って 適化を行います。これに対して、ポインタの 適化は、以下の前提条件を付けて 適化を行います。

・ 前提条件 1同じ領域を異なるポインタ変数が指すことはない。

・ 前提条件 2同じ領域に対して、ポインタ変数でアクセスする場合とポインタ変数を使わずに直接アクセスする場合が混在することはない。

たとえば、ポインタ変数でアクセスする領域が、malloc 関数などで動的に確保した領域に限られていることが明らかな場合は、前提条件 2 を満足します。

double a[100], b[100], c[100];double x, y;

...for(i=0; i<100; i++){ a[i] = b[i] * x * c[i] * y;

double a[100], b[100], c[100];double x, y;

...t = x * y;for(i=0; i<100; i++){ a[i] = b[i] * c[i] * t;

...

float a[10], b[10], v;...for(i=0; i<10; i++) a[i] = b[i] / v;

float a[10], b[10], v;...t = 1.0 /v;for(i=0; i<10; i++) a[i] = b[i] * t;

32

第 3 章 逐次 適化機能

これらの前提条件を付けることにより、共通式の除去や不変式の移動などの 適化が、ポインタ変数を使わずにアクセスする場合と同様に行われるので、高速なオブジェクトプログラムが得られます。ただし、上記の前提条件を満足しないプログラムに対して、ポインタの 適化を行った場合は、使用者が意図した結果が得られないことがあります。ポインタの 適化は、-Kpopt オプションで制御することができます。

例 1:ポインタの 適化(前提条件 1 の説明)

[ 説明 ]ポインタ変数 p とポインタ変数 q は、同じ領域を指していないという前提で 適化します。その結果、*p+100 は共通式とみなされます。もし、ポインタ変数 p とポインタ変数 q が同じ領域を指している場合は、利用者が意図した結果になりません。

例 2:ポインタの 適化(前提条件 2 の説明)

[ 説明 ]ポインタ変数 p は、変数 a1,a2,b,x を指していないという前提で 適化します。その結果、*p+b は共通式とみなされます。もし、ポインタ変数 p が変数 a1 または変数 x を指している場合は、利用者が意図した結果になりません。

3.4 適化機能の活用方法

適化機能を有効に活用するための機能について説明します。

3.4.1 適化制御行 (OCL) の利用適化にとって有効な情報をソースプログラム上に記述することにより、 適化の効果をより高

めることができます。#pragma 行に以下の記述がある場合、それを 適化制御行と呼びます。

適化制御行は、-Kocl オプションで制御することができます。

3.4.1.1 適化制御行 (OCL) の種類適化制御行の種類とその有効範囲を「表 3.1 適化制御行と有効範囲」に示します。

global 行指定された 適化指示子を翻訳単位内すべてに有効にします。

書式#pragma global 適化指示子

挿入位置対象にしたい翻訳単位の先頭に記述します。

表 3.1 適化制御行と有効範囲

前処理字句列 適化制御行の名称 適化の有効範囲

global global 行 翻訳単位内

procedure procedure 行 関数内

loop loop 行 直後のループ

a1 = *p + 100;*q = 0;a2 = *p + 100;

a1 = *p + 100;*q = 0;a2 = a1; /* 共通式の除去により変更 */

a1 = *p + b;x = 0;a2 = *p + b;

a1 = *p + b;x = 0;a2 = a1; /* 共通式の除去により変更 */

33

C++ 言語使用手引書

procedure 行指定された 適化指示子を関数内で有効にします。

書式#pragma procedure 適化指示子

挿入位置対象にしたい関数の宣言文(宣言と同時に初期値を設定している文も含みます)と 初の実行文の間に記述します。

loop 行指定された 適化指示子を直後のループで有効にします。

書式#pragma loop 適化指示子

挿入位置対象にしたいループの直前に記述します。

注意適化指示行に指定できる 適化指示子は1つです。global 行、procedure 行および loop 行で

は、複数の 適化指示行を連続して記述することにより、複数の 適化指示子が有効となります。

3.4.1.2 適化指示子の種類「表 3.2 適化制御行に指定できる 適化指示子」に、逐次 適化に対する 適化指示子を以下に示します。

○: 適化指示子を 適化制御行に指定できます。×: 適化指示子を 適化制御行に指定できません。

表 3.2 適化制御行に指定できる 適化指示子

適化指示子 機能説明

指定できる 適化

制御行注

注 .G: global 行P: procedure 行L: loop 行

G P L

evalnoeval

演算の評価方法を変更する 適化を行うか否かを指示します。

○ ○ ○

fmaddnofmadd

加減算と乗算を含む式の 適化を行うか否かを指示します。

○ ○ ○

preexnopreex

不変式の先行評価を行うか否かを指示します。 ○ ○ ○

unroll [ml] 対応するループをアンローリングすることを指示します。ml はループ・アンローリングの展開数(多重度)を指定します。ml は 2 ~ 100 の 10 進数です。

○ ○ ○

nounroll 対応するループをアンローリングしないことを指示します。

○ ○ ○

34

第 3 章 逐次 適化機能

3.4.2 プロファイル情報の利用プログラムの実行状況を示す情報(プロファイル情報と呼びます)をいったんファイルに出力して、それをコンパイラが参照しながら 適化することにより、より高速なオブジェクトプログラムを生成することができます。プロファイル情報を利用した 適化は、以下の 2 段階を経て行われます。

第 1 段階 : プロファイル情報の生成 通常のオプションの他に、-Kpg を指定して翻訳します。 -Kpg を指定して翻訳したプログラムを実行すると、プロファイル情報ファイルにプロファイル情報が生成されます。

第 2 段階 : プロファイル情報の利用 通常のオプションの他に、-Kpu を指定して翻訳します。 -Kpu を指定して翻訳すると、第 1 段階で作成されたプロファイル情報を 適化に活かした、より高速なオブジェクトプログラムが得られます。

第 1 段階と第 2 段階は、一緒に行うことはできません。また、-Kpg と一緒に指定した翻訳時オプションと、-Kpu と一緒に指定した翻訳時オプションは、並び順も含めて内容が一致しなければなりません。異なる場合、メッセージが出力され翻訳が中断します。 以下に、プロファイル情報を利用してロードモジュールを作成し、それを実行するまでのコマンドの例を示します。

1.FCC sample.cc -Kfast -Kpg : プロファイル情報を生成する準備 2.a.out : プロファイル情報を実際に生成 3.FCC sample.cc -Kfast -Kpu : プロファイル情報を利用して 適化 4.a.out : より高速化されたロードモジュールの実行

上記の (1) および (2) が第 1 段階、(3) が第 2 段階です。 プロファイル情報は、ソースプログラムの名前の後ろに .d を付加した名前のプロファイル情報ファイルに生成されます。すでにファイルがある場合、累積する形で情報が書き込まれます。そのとき、以前に作成したときと翻訳時オプションが一致しているか否かが調べられ、一致しない場合、実行が中断されます。 以下に、3 つの入力データについてプログラム実行し、プロファイル情報を累積するコマンドの例を示します。これらは、すべて第 1 段階の作業です。

1.FCC sample.cc -Kfast -Kpg 2.[rm sample.cc.d] 3.a.out < case1.data 4.a.out < case2.data 5.a.out < case3.data 適化制御行で if 文の条件の成立確率が指定されている場合、プロファイル情報が優先し、そ

の 適化制御行は無効になります。なお、分岐 (if 文など ) が全くないプログラムや 適化により分岐がすべて削除された場合、プロファイル情報は生成されませんし、参照もされません。

3.4.3 実行マシン属性の選択実行可能プログラムを実行するマシンの種別を翻訳時オプションで指定することにより、そのマシンに も適したオブジェクトプログラムが出力され、より高速化することができます。マシンの属性としては、以下の 2 種類があります。

CPU の種類を示すものこれを指定する翻訳時オプションとして、-Kcpu があります。cpu には、SPARC64_GP、SPARC64_GP2、SPARC64VI、ULTRA、ULTRA1 または ULTRA2 が指定できます。-Kcpu が指定されない場合には、-KULTRA2 が指定されたと見なされます。-Kcpu を指定することにより、各 CPU に 適な命令選択と命令スケジューリングが行われます。

SPARC アーキテクチャの世代を示すもの これを指定する翻訳時オプションとして、-Karchi があります。archi には、V8、V8PFMADD、V8PLUS、V9 または V9FMADD が指定できます。-Karchi が指定されない場合には、-KV8 が指定されたと見なされます。

マシン属性の自動選択翻訳時オプション -Kfast を指定することにより、マシンの属性をコンパイラに自動的に選択させることができます。

35

C++ 言語使用手引書

-Kfast が指定された場合、コンパイラは、コンパイラが動作しているマシンの属性を実行マシンの属性として採用します。すなわち、コンパイラは、-KSPARC64_GP、-KSPARC64_GP2、-KSPARC64VI、-KULTRA、-KULTRA1、-KULTRA2 の中から、コンパイラが動作しているマシンに適したオプションを自動的に選択します。

実行マシンの注意事項-KV8PFMADD または -KV9FMADD が有効な場合、multiply add/subtract 浮動小数点演算命令が生成されます。この命令は、浮動小数演算精度に影響を与えることがあります。この命令を抑止するには、-KNOFMADD を指定してください。

3.4.4 適化機能の選択の目安ここでは、プログラムを高速に実行できるようなオブジェクトプログラムを生成するために、適化機能をどのように使用したらよいかの目安について説明します。

適化機能を使用しない場合適化に関する翻訳時オプションを何も指定しなければ、 適化は行われません。通常、デバッ

グ中のプログラムは、 適化機能を使用しないで翻訳します。

一般的なプログラムを平均的に高速化する場合一般的なプログラムを、平均的に高速に実行できるようなオブジェクトプログラムを生成するために、 適化機能の一般的な使用方法について説明します。以下に示すような、翻訳時オプションの指定と再翻訳だけでソースに手を入れることなく性能向上が可能です。

実行マシン属性からの選択

実行マシンの属性 (「3.4.3 実行マシン属性の選択」を参照 ) を考慮して、以下の翻訳時オプションを指定します。

翻訳マシンと同じマシン属性上で実行することを前提とした場合-Kfast を指定します。

翻訳マシンと異なるマシン属性上で実行することを想定した場合-O オプションを指定します。

関数のインライン展開の選択

関数をインライン展開 (「3.3.1 インライン展開」を参照 ) する場合は、以下の翻訳時オプションを指定します。

標準関数のインライン展開の選択-Klib を指定します。標準関数と同じ名前の関数を利用者が定義している場合、利用者の意図した結果にならない場合があります。なお、-Klib は、-Kfast に含まれていますので、-Kfast を指定した場合、-Klib を指定する必要はありません。

ソースプログラム上で定義された関数のインライン展開の選択 -x オプションを指定します。-x n で指定する値 n は、一般的に 10 ~ 50 の範囲が妥当です。

プログラムの性質を活かした 適化を行う場合プログラムを、より高速に実行できるようなオブジェクトプログラムに生成する場合に有効です。-O オプションおよび拡張 適化機能 (-Kopt) の中から、プログラムの性質に見合った翻訳時オプションを指定します。

さらにプログラムを高速に実行したい場合、ツール注 などを使用しながら、性能ネックとなる部分を確認することも必要です。その結果、 適な翻訳時オプションとなるように調整し、場合によってはソースプログラムに手を加えることなども必要です。

注 .性能ネックを検出するツールには、プログラミング支援ツール (Parallelnavi 環境 )、あるいは並列アナライザ ( 非 Parallelnavi 環境 ) があります。

36

第 4章 並列化機能

この章では、本処理系を使用して、C++ 言語プログラムを並列処理する方法について記述しています。

4.1 並列処理の概要

ここでは、C++ 言語プログラムの並列処理の概要と、本処理系の並列機能の特徴について説明しています。

4.1.1 並列処理とは並列処理という言葉は広い意味に使われていますが、ここで述べる並列処理とは、独立に動作可能な複数の CPU を同時に使って、一つのプログラムを実行することを意味します。ここでは、複数のプログラムを同時に実行するマルチジョブのことを、並列処理とは言わないことにします。

「図 4.1 並列処理のイメージ」に、同時に複数の CPU を利用して並列処理する様子を示します。

図 4.1 並列処理のイメージ

4.1.2 並列処理の効果並列処理の効果は、複数の CPU を同時に使うことによって、プログラムの経過時間が短縮されることです。例えば、「図 4.1 並列処理のイメージ」に示すように、for ループを分割して二つのfor ループを並列実行できたとすると、この for ループを実行するのにかかる時間は、理想的には半分になります(「図 4.2 並列処理による経過時間の短縮」)。

for(i=0; i<1000; i++){ a[i] = b[i] + c[i];}

for ループを分割して、複数の CPU 上で同時に実行する。

CPU0 CPU1

for(i=0; i<500; i++){ a[i] = b[i] + c[i];}

for(i=500; i<1000; i++){ a[i] = b[i] + c[i];}

CPU0 CPU1

for(i=500; i<1000; i++)

1 個の CPU 上で逐次処理 2 個の CPU 上で並列処理

二つの CPU で同時に実行されることにより、経過時間が短縮される。

経過時間

for(i=0; i<500; i++)for(i=0; i<500; i++)

for(i=500; i<1000; i++)

37

C++ 言語使用手引書

図 4.2 並列処理による経過時間の短縮

しかし、並列処理によってプログラム実行の経過時間の短縮は可能ですが、プログラム実行に要する CPU 時間を減らすことはできません。なぜなら、並列処理では複数の CPU を利用しますが、それぞれの CPU の消費する CPU 時間の合計は、プログラムを逐次的に実行した場合の CPU 時間と同等か、または、並列処理に必要なオーバヘッドの分だけ増加するためです。並列処理プログラムの性能は、一般に、実行に要した CPU 時間の短縮ではなく、経過時間の短縮で評価することに注意してください。逐次的に動作していたプログラムを並列処理によって実行した場合、並列処理のためのオーバヘッドによってプロセッサ全体で消費する CPU 時間の合計は、逐次処理時の CPU 時間よりも大きくなります。

4.1.3 並列処理で効果を得るための条件並列処理で経過時間を短縮するためには、複数の CPU を同時に使える計算機環境が必要です。本処理系を使用して作成した並列処理プログラムは、単一の CPU しかもたないハードウェアでも実行可能ですが、この場合には経過時間の短縮は望めません。また、複数の CPU をもつハードウェア上でも、他のジョブが動いていて計算機全体として CPU 時間が不足しているような状況下では、経過時間の短縮は難しくなります。これは、並列処理プログラムの実行のために、同時に複数の CPU が割り当てられる機会が少なくなるためです。つまり、並列処理で効果を得るためには、複数の CPU をもつハードウェア上で、かつ、システム全体としてCPU処理能力に余裕のある環境下で、並列処理プログラムを実行する必要があります。また、並列処理のためのオーバヘッドを相対的に小さくするため、ループの繰返し数またはループ中の実行文数が多いことが必要です。

4.1.4 本処理系の並列機能の特徴本処理系は、自動並列化機能および OpenMP 仕様に基づいた並列化機能を提供します。自動並列化は、本処理系が自動的にプログラムを並列処理することです。自動並列化の対象となるのは、本処理系が並列化可能であると認識できる for ループ、while ループおよび if-gotoループ(以降、単にループと呼びます)に限られますが、プログラムの書き換えなどのユーザ負担を軽減できます。自動並列化の機能を利用する場合、逐次実行可能なソースプログラムに、何ら手を加える必要はありません。したがって、プログラムが C++ 言語規格に合致している限り、他の処理系ソースプログラムを移植するのは容易です。また、本処理系には、自動並列化を促進する 適化制御行が用意されています。 適化制御行は、利用者がコンパイラに自動並列化の参考になる情報を通知し、効率の良いオブジェクト生成を促進するために用いられます。自動並列化については、「4.2 自動並列化」をお読みください。OpenMP 仕様による並列化については、「4.3 OpenMP 仕様による並列化」をお読みください。

4.2 自動並列化

ここでは、本処理系で提供している自動並列化について説明します。

4.2.1 翻訳・実行の方法ここでは、自動並列化機能を使うための翻訳および実行の方法について説明します。

4.2.1.1 翻訳の方法自動並列化の機能を使用するには、翻訳時オプションとして -Kparallel を指定します。

4.2.1.1.1 自動並列化のための翻訳時オプション自動並列化機能に関連するオプションの形式と意味を以下に説明します。

-Kparallel[ , reduction, instance=N, ocl, pmsg ]

-Kparallel自動並列化を行います。-O3 が誘導されます。-O0、-O1 または -O2 を同時に指定した場合、指定の順序に関係なく -O3 に変更されます。-g と同時に指定できません。同時に指定した場合、-Kparallel は無効となります。

38

第 4 章 並列化機能

-Kparallel は、結合編集時にも指定する必要があります。-Kparallel を指定して翻訳されたオブジェクトプログラムが含まれる場合は、結合編集時に -Kparallel を指定する必要があります。

例:$ FCC a.cc -Kparallel -c$ FCC a.o -Kparallel

-Kreduction-Kparallel と同時に指定した場合に有効です。リダクションの 適化(「4.2.3.1.7 リダクションによるループスライス」を参照)を行います。この 適化を行うと、結果に精度差が生じる可能性があります。利用者は、翻訳時の診断メッセージにより、この 適化が行われたかどうか知ることができます。-Kparallel と -Keval を同時に指定した場合にも、リダクションの 適化を行います。

-Kinstance=N-Kparallel と同時に指定した場合に有効です。コンパイラは実行時のスレッドの数を N に想定したオブジェクトプログラムを出力します。これによって、自動並列化された for ループの回転数を計算する命令が軽減されて、実行性能が向上します。翻訳時オプション -Kparallel,instance=N で、並列動作のスレッド数を指定する場合、実行時のスレッド数と同じ値でなければなりません。N の値が実行時のスレッド数と異なる場合、実行結果を保証できません。

-Kocl-Kparallel と同時に指定した場合に有効です。自動並列化を促進する 適化制御行(「4.2.3.2 適化制御行」を参照)を有効にします。

-Kpmsg-Kparallel と同時に指定した場合に有効です。翻訳時メッセージにより、自動並列化されたループを通知します。

4.2.1.2 実行の方法自動並列化されたプログラムを実行させるときは、環境変数 PARALLEL で、並列に動作させるスレッドの数を指定することができます。また、環境変数 THREAD_STACK_SIZE で、スレッド毎のスタック領域の大きさを指定することができます。さらに、環境変数 FLIB_SPINWAIT で、スレッドの同期待ちの方法を変更することができます。その他の実行に関する手続きは、逐次実行のときと同じです。

4.2.1.2.1 環境変数 PARALLEL環境変数 PARALLEL で、並列に動作させるスレッドの数を指定することができます。スレッド数の決定方法の詳細については、「4.2.1.2.2 スレッド数」をお読みください。

4.2.1.2.2 スレッド数並列に動作するスレッドの数は、まず以下の優先順位で決定されます。

1.環境変数 PARALLEL の指定値注

2.環境変数 OMP_NUM_THREADS の指定値3.Solaris プロセッサセットの CPU 数4.1

上記の優先順位で決まったスレッド数と、CPU 数の上限値を比較して、小さい方を 終的なスレッド数として採用します。なお、CPU 数の上限値は、次のように決定されます。

Solaris プロセッサセットが定義されている場合

注 .結合編集時に -KOMP が指定され、かつ環境変数 FLIB_FASTOMP に TRUE が設定されているとき、環境変数 OMP_NUM_THREADS の指定値があれば、その値と一致していなければなりません。一致していない場合には、小さい方の値が採用されます。この時に、環境変数FLIB_C_MESSAGE が存在する場合には、 mpc1042i-w のメッセージが出力されます。

39

C++ 言語使用手引書

・ プロセッサセット内では、プロセッサセットの CPU 数

・ プロセッサセット外では、システムの CPU 数

ただし、自動並列のスレッド数が 128 を超えた場合の動作は保証されません。環境変数 PARALLEL に指定する値は 128 以下にしてください。

Solaris プロセッサセットが定義されていない場合

・ システムの CPU 数

環境変数 OMP_NUM_THREADS については、「4.3.1.2.2 OpenMP 仕様の環境変数」をお読みください。Parallelnavi 環境下で実行する場合のスレッド数については、「付録 C Parallelnavi」をお読みください。

4.2.1.2.3 環境変数 THREAD_STACK_SIZE環境変数 THREAD_STACK_SIZE で、スレッド毎のスタック領域の大きさを K バイト単位で指定することができます。スタック領域の詳細については、「4.2.1.2.4 実行時の領域」をお読みください。

4.2.1.2.4 実行時の領域自動並列化されたループ内でローカルな変数は、スタック領域に割り付けられます。これらの変数が多い場合には、スタック領域を十分な大きさに拡張する必要があります。プロセスのスタック領域は、limit(1) コマンドで設定が可能です。スレッド毎のスタック領域は、プロセスのスタック領域と同じ大きさで確保されます。ただし、プロセスのスタック領域の制限値が、使用可能な実装メモリと仮想メモリの大きさの小さい方をスレッド数で割った値より大きい場合、本システムがスレッド毎のスタック領域の大きさを次のように仮定して確保します。なお、仮想メモリの大きさとは、limit(1) コマンドの仮想記憶の 大サイズとして表示される値です。S = ( M/T ) / 5S: スレッド毎のスタック領域の大きさ(byte)M: 実装メモリと仮想メモリの小さい方の大きさ(byte)T: スレッド数

スレッド毎のスタック領域の大きさを、特定の大きさで確保したい場合には、環境変数THREAD_STACK_SIZE を使用してください。

4.2.1.2.5 同期待ち処理環境変数 FLIB_SPINWAIT で、同期待ち処理を調節することができます。デフォルトは unlimitedです。unlimited: 同期が獲得できるまでスピン待ちを行います。0: スピン待ちを行わず、サスペンド待ちを行います。<n>s:n 秒間スピン待ちし、その後サスペンド待ちに移ります。<n>ms:n ミリ秒間スピン待ちし、その後サスペンド待ちに移ります。<n> は 0 以上の整数

スピン待ちとは、スレッド間で同期を待ち合うとき、CPU 時間を消費する方法で待たせる方式です。逆に、サスペンド待ちは CPU 時間を消費せずに待たせます。スピン待ちを行う方が並列処理のオーバヘッドが少ないため、経過時間を重視する場合には、unlimited を選択してください。CPU 時間を重視する場合は、0 を選択してください。

4.2.1.3 翻訳・実行の例

例 1:$ FCC -Kparallel,reduction,ocl test1.cc$ a.out例 1 は、リダクションの 適化と 適化制御行を有効にして、ソースプログラムを翻訳します。このプログラムは、1 個のスレッドを使用して動作します。

例 2:$ FCC -Kparallel test2.cc$ setenv PARALLEL 2$ a.out$ setenv PARALLEL 4$ a.out

40

第 4 章 並列化機能

環境変数 PARALLEL に値 2 を設定して、2 個のスレッドを使用して動作させます。次に、環境変数 PARALLEL に値 4 を設定して、4 個のスレッドを使用して動作させます。

例 3:$ psrinfo0 on-line since 01/01/01 00:00:001 on-line since 01/01/01 00:00:002 on-line since 01/01/01 00:00:003 on-line since 01/01/01 00:00:00$ FCC -Kparallel test3.cc$ setenv PARALLEL 3$ a.outまず、psrinfo コマンドで、アクティブ CPU 数(on-line の CPU 数)が 4 であることを確認します。次に、環境変数 PARALLEL に値 3 を設定して、3 個のスレッドを使用して動作させます。なお、これは、Parallelnavi がインストールされていないシステムにおいてプログラムを並列に動作させている例です。Parallelnavi がインストールされているシステムに関しては、「付録C Parallelnavi」をお読みください。

4.2.2 並列化プログラムのチューニング並列化したプログラムをチューニングする手段として、実行時間のサンプリング機能を利用することができます。実行時間の情報により、プログラムのどの文の実行コストが高いかを知ることができます。プログラムを高速に実行させるには、実行コストの高い文が並列に動作するようにプログラミングします。

4.2.3 自動並列化処理の詳細ここでは、自動並列化処理の各機能の詳細および留意事項について説明します。

初に自動並列化について説明し、次に自動並列化を促進するための 適化制御行について説明します。 後に自動並列化機能を使うときの留意事項について説明します。

4.2.3.1 自動並列化ここでは、本処理系のもつ自動並列化機能について説明します。

4.2.3.1.1 自動並列化の対象自動並列化機能は、C 言語ソースプログラム中のループ(多重ループも含みます)とポインタ演算を並列化の対象にします。

4.2.3.1.2 ループスライスとは自動並列化機能は、ループを複数に分割します。そして分割されたループを並列に実行することで、経過時間の短縮を図ります。この並列化をループスライスと呼びます。「図 4.3 ループスライスのイメージ」に、ループスライスのイメージを示します。

図 4.3 ループスライスのイメージ

for(i=0; i<10000; i++){ a[i] = b[i] + c[i];}

for(i=0; i<5000; i++){ a[i] = b[i] + c[i];}

for(i=5000; i<10000; i++){ a[i] = b[i] + c[i];}

41

C++ 言語使用手引書

4.2.3.1.3 コンパイラによる自動ループスライス本処理系は、ループスライスを行ってもデータの定義引用順序が変わらないようなループを自動並列化の対象として選択して、並列実行の結果が逐次実行の結果と同じになるようにします。

「図 4.4 ループスライスができないループの例」に、自動ループスライスの対象にならない例を示します。この for ループでは、本来、for 文の制御変数 i が 4999 のときに定義された配列要素 a[4999] の値を、for 文の制御変数 i が 5000 の時に引用しなければなりません。しかし、この for ループを単純にループスライスして並列に実行すると、a[4999] を定義する前に引用する可能性があり、実行結果を誤ることになります。

図 4.4 ループスライスができないループの例

4.2.3.1.4 ループ交換と自動ループスライス多重ループに対してループスライスを実施する場合、本処理系は、ループスライスが可能なループを選択し、可能ならばループの交換を行い、できるだけ外側のループをループスライスします。これは、できるだけ並列処理制御の回数を少なくしてオーバヘッドを削減し、実行性能を向上させるためです。ループ交換は、-Kparallel に加え、-Keval が指定されたときにだけ行われます。

for(i=1; i<10000; i++){ a[i] = a[i-1] + b[i];}

for(i=1; i<5000; i++){ a[i] = a[i-1] + b[i];}

for(i=5000; i<10000; i++){ a[i] = a[i-1] + b[i];}

42

第 4 章 並列化機能

「図 4.5 多重ループでのループ交換」に、多重ループにおいて for ループが交換されてループスライスされた例を示します。制御変数 i について並列化されますが、i を外側のループにすることで、並列処理制御の回数を少なくすることができます。

図 4.5 多重ループでのループ交換

4.2.3.1.5 ループ分割と自動ループスライス「図 4.6 ループの分割」のループでは、配列 a は、ループスライスを行うとデータの定義引用順序が変わるため、ループスライスすることができません。配列 b は、データの定義引用順序が変わらないので、ループスライスできます。このような場合、配列 a を定義している文と配列 b を定義している文を 2 つのループに分割して、配列 b を定義するループの方をループスライスします。

「図 4.6 ループの分割」に、for ループが分割されてループスライスされた例を示します。

for(i=0; i<10000; i++){ for(j=1; j<10; j++){ a[j][i] = a[j][i] + b[j][i]; }}

交換for(j=1; j<10; j++){ for(i=0; i<10000; i++){ a[j][i] = a[j][i] + b[j][i]; }}

for(j=1; j<5; j++){ for(i=0; i<10000; i++){ a[j][i] = a[j][i] + b[j][i]; }}

for(j=5; j<10; j++){ for(i=0; i<10000; i++){ a[j][i] = a[j][i] + b[j][i]; }}

43

C++ 言語使用手引書

図 4.6 ループの分割

4.2.3.1.6 ループ融合と自動ループスライス「図 4.7 ループの融合」では、回転数の同じループが二つ連続しています。このような場合、ループを一つに融合することで、ループ制御のオーバヘッドを軽減するとともに、並列処理制御の回数を減らすことができます。

「図 4.7 ループの融合」に、ループを融合してループスライスされた例を示します。

図 4.7 ループの融合

for(i=1; i<10000; i++){ a[i] = a[i-1] + c[i]; b[i] = b[i] + c[i];}

for(i=1; i<10000; i++){ a[i] = a[i-1] + c[i];}

for(i=1; i<10000; i++){ b[i] = b[i] + c[i];}

分割

for(i=5000; i<10000; i++){ b[i] = b[i] + c[i];}

for(i=1; i<5000; i++){ b[i] = b[i] + c[i]; }

2 つ目のループを並列化

for(i=0; i<10000; i++){ a[i] = b[i] + c[i];}for(i=0; i<10000; i++){ d[i] = e[i] + f[i];}

融合

for(i=0; i<10000; i++){ a[i] = b[i] + c[i]; d[i] = e[i] + f[i];}

for(i=0; i<5000; i++){ a[i] = b[i] + c[i]; d[i] = e[i] + f[i];}

for(i=5000; i<10000; i++){ a[i] = b[i] + c[i]; d[i] = e[i] + f[i];}

44

第 4 章 並列化機能

4.2.3.1.7 リダクションによるループスライス翻訳時オプションに -Kparallel と -Kreduction を同時に指定したときに、自動並列化される場合があります。この並列化は、逐次実行のときと計算結果に精度差を生じる可能性がありますが、加算および乗算などの交換可能な演算の順序を変更してループスライスを行います。リダクションの対象になるのは、ループ内に以下の演算が含まれる場合です。

・ 総和を求める演算がある場合

例: s = s + a[i];

・ 総積を求める演算がある場合

例: p = p * a[i];

・ 内積を求める演算がある場合

例: p = p + a[i] * b[i];

・ 小値を求める演算がある場合

例: x = min(x, a[i]);

・ 大値を求める演算がある場合

例: y = max(y, a[i]);

・ ビット OR 演算がある場合

例: n = n | a[i];

・ ビット AND 演算がある場合

例: m = m & a[i];

「図 4.8 リダクションによる自動ループスライス」に、リダクションによるループスライスの例を示します。

図 4.8 リダクションによる自動ループスライス

4.2.3.1.8 ループスライスされないループ以下に示すループは、ループスライスの対象となりません。・ 並列実行しても実行時間が短縮されないと予想される場合・ 関数の引用を含む場合・ ループの形が複雑な場合・ 標準関数を含む場合・ データの定義引用順序が逐次実行のときと変わるおそれがある場合

sum = sum + sum1 + sum2;

sum = 0;for(i=0; i<10000; i++){ sum = sum + a[i];}

sum1 = 0;for(i=0; i<5000; i++){ sum1 = sum1 + a[i];}

sum2 = 0;for(i=5000; i<10000; i++){ sum2 = sum2 + a[i];}

45

C++ 言語使用手引書

並列実行しても実行時間が短縮されないと予想される場合ループの回転数が小さい場合や、ループ内の演算数が少ない場合は、並列実行に伴うオーバヘッドのため、ループスライスを行うと、逐次処理した場合よりも性能が低下することがあります。そのため、性能が向上しないと予想されるループについては、本処理系はループスライスを行いません。

「図 4.9 回転数が小さく、演算数が少ないループ」に、回転数が小さく、演算数が少ないループの例を示します。

図 4.9 回転数が小さく、演算数が少ないループ

関数の引用を含む場合関数の引用を含むループはループスライスの対象となりません。内部ループに、関数の引用が含まれているループも同様です。ただし、 適化制御行によって、並列化を促進することができます。詳細については、「4.2.3.2

適化制御行」をお読みください。また、関数がインライン展開された場合は、並列化の対象になります。

「図 4.10 関数の引用を含むループ」に関数の引用を含むループの例を示します。

図 4.10 関数の引用を含むループ

ループの形が複雑な場合以下に示すループは、形が複雑なため、ループスライスの対象となりません。

・ ループの内側から外側へ飛び出しがあるループ

「図 4.11 飛び出しのあるループ」に、飛び出しのあるループの例を示します。

図 4.11 飛び出しのあるループ

標準関数を含む場合標準関数は、ループスライスの対象になるものとならないものがありますが、診断メッセージによって知ることができます。

データの定義引用順序が逐次実行のときと変わるおそれがある場合

for(i=0; i<10; i++){ a[i] = a[i] + b[i];}

回転数が小さく、かつ演算数も少ないため、ループスライスの対象となりません。

for(j=0; j<10; j++){ for(i=0; i<10000; i++){ a[j][i] = a[j][i] + b[j][i]; func(a); }}

関数呼出しの引用が含まれるため、ループスライスの対象となりません。

for(j=0; j<10; j++){ for(i=0; i<10000; i++){ a[j][i] = a[j][i] + b[j][i]; if(a[j][i]<0) goto out; }}out:;

for ループ外への飛び出しがあるため、ループスライスの対象となりません。

46

第 4 章 並列化機能

「図 4.4 ループスライスができないループの例」の例で説明したように、データの定義引用順序が逐次実行のときと変わるループはループスライスの対象となりません。

4.2.3.1.9 自動並列化状況の表示自動並列化が行われたかどうか、行われたとしたらどのように行われたかを知りたいときは、翻訳時オプションに -Kparallel と -Kpmsg を同時に指定してください。翻訳時の診断メッセージによって、知ることができます。自動並列化が行われなかった理由も、同様に知ることができます。

4.2.3.2 適化制御行本処理系には、自動並列化を促進するために、 適化制御行が用意されています。自動並列化を促進する 適化制御行を有効にするには、-Kparallel と -Kocl を同時に指定してください。

4.2.3.2.1 適化指示子の種類適化制御行は、指定される 適化指示子の種類によって、機能が異なります。

「表 4.1 自動並列化用の 適化指示子一覧」に、 適化指示子の種類と機能を示します。自動並列化用の 適化指示子は、利用者がコンパイラに自動並列化の参考になる情報を通知し、効率の良いオブジェクトプログラムを生成するために用いられます。

○:指定可能×:指定不可備考: ary,ext,var は使用する前に宣言してください。

4.2.3.2.2 自動並列化の 適化指示子自動並列化用の 適化指示子を指定した場合であっても、ループスライスの対象とならない forループについては、 適化指示子の効果は無効になります。ループスライスの対象とならないループについては、「4.2.3.1.8 ループスライスされないループ」をお読みください。

表 4.1 自動並列化用の 適化指示子一覧

適化指示子 意味概略

指定できる適化指示行

global行

procedure行

loop行

serial 自動並列化機能を無効にすることを指示します。

○ ○ ○

parallel 自動並列化機能を有効にすることを指示します。

○ ○ ○

norecurrence [ary,..]disjoint [ary,...]

ループスライス可能な配列 ary を指示します。

○ ○ ○

temp [var,...] ループ内で一時的に使用している変数varを指示します。

○ ○ ○

independent [ext,...] 関数(ext)引用のあるループスライスを指示します。

× ○ ○

reductionnoreduction

リダクション演算を並列化するか否かを指示します。

○ ○ ○

47

C++ 言語使用手引書

4.2.3.2.3 自動並列化用の 適化指示子自動並列化用の 適化指示子には、次の種類があります。

serial 指示子serial 指示子は、ループのループスライスを抑止する場合に使用します。例えば、あるループは、逐次実行させた方が速いとわかっている場合に使用します。

「図 4.12 serial 指示子のないプログラムの例」のプログラムで、ループ 2 をループスライスしたくない場合、「図 4.13 serial 指示子の使用例」のように serial を指定することにより、ループ 2 のループスライスを止めることができます。

図 4.12 serial 指示子のないプログラム例

for(j=0; j<10; j++){ for(i=0; i<l; i++){ ループ 1 a1[j][i] = a1[j][i] + b1[j][i]; }}

・・・

for(j=0; j<10; j++){ for(i=0; i<m; i++){ ループ 2 a2[j][i] = a2[j][i] + b2[j][i]; }}

・・・

for(j=0; j<10; j++){ for(i=0; i<n; i++){ ループ 3 a3[j][i] = a3[j][i] + b3[j][i]; }}

並列動作

並列動作

並列動作

48

第 4 章 並列化機能

図 4.13 serial 指示子の使用例

parallel 指示子parallel 指示子は、serial の効果を打ち消して、一部のループだけをループスライスの対象とする場合に使用します。

「図 4.14 parallel 指示子のないプログラム例」で、ループ 2 のループだけをループスライスの対象にしたい場合、「図 4.15 parallel 指示子の使用例」のように serial と parallel を併用することにより、ループ 2 のループだけをループスライスの対象にすることができます。

図 4.14 parallel 指示子のないプログラム例

for(j=0; j<10; j++){ for(i=0; i<l; i++){ ループ 1 a1[j][i] = a1[j][i] + b1[j][i]; }}

・・・

#pragma loop serialfor(j=0; j<10; j++){ for(i=0; i<m; i++){ ループ 2 a2[j][i] = a2[j][i] + b2[j][i]; }}

・・・

for(j=0; j<10; j++){ for(i=0; i<n; i++){ ループ 3 a3[j][i] = a3[j][i] + b3[j][i]; }}

並列動作

逐次動作

並列動作

for(j=0; j<10; j++){ for(i=0; i<l; i++){ ループ 1 a1[j][i] = a1[j][i] + b1[j][i]; }}

・・・

for(j=0; j<10; j++){ for(i=0; i<m; i++){ ループ 2 a2[j][i] = a2[j][i] + b2[j][i]; }}

・・・

for(j=0; j<10; j++){ for(i=0; i<n; i++){ ループ 3 a3[j][i] = a3[j][i] + b3[j][i]; }}

並列動作

並列動作

並列動作

49

C++ 言語使用手引書

図 4.15 parallel 指示子の使用例

disjoint 指示子および norecurrence 指示子disjoint 指示子および norecurrence 指示子は、ループ内の演算対象となる配列の定義引用順序が、ループスライスを行っても逐次実行の時と変わらないことを本処理系に指示します。norecurrence 指示子は、disjoint 指示子と等価です。これにより、配列の定義引用順序が不明でループスライスできなかったループを、ループスライスの対象にします。

「図 4.16 disjoint 指示子のないループの例」の場合、配列 a の添字式が別の配列要素 l[i] であるため、本処理系は配列 a がループスライスしても問題がないか判断できません。したがって、この外側のループはループスライスされません。

図 4.16 disjoint 指示子のないループの例

もし配列 a がループスライスしても問題がないと分かっているのであれば、「図 4.17 disjoint指示子の使用例」のように disjoint を使用することにより、この外側のループはループスライスされます。

図 4.17 disjoint 指示子の使用例

注意事項

#pragma global serialfor(j=0; j<10; j++){ for(i=0; i<l; i++){ ループ 1 a1[j][i] = a1[j][i] + b1[j][i]; }}

・・・

#pragma loop parallelfor(j=0; j<10; j++){ for(i=0; i<m; i++){ ループ 2 a2[j][i] = a2[j][i] + b2[j][i]; }}

・・・

for(j=0; j<10; j++){ for(i=0; i<n; i++){ ループ 3 a3[j][i] = a3[j][i] + b3[j][i]; }}

逐次動作

並列動作

逐次動作

for(j=0; j<1000; j++){ for(i=0; i<1000; i++){ a[j][l[i]] = a[j][l[i]] + b[j][i]; }}

#pragma loop disjoint afor(j=0; j<1000; j++){ for(i=0; i<1000; i++){ a[j][l[i]] = a[j][l[i]] + b[j][i]; }}

並列動作

50

第 4 章 並列化機能

disjoint 指示子をループスライス不可能な配列に対して指定した場合、本処理系は誤ったループスライスを行うことがあります。

temp 指示子temp 指示子は、ループ内で引用されている変数がそのループの中で一時的に使用されていることを、本処理系に指示するために使用します。これにより、並列化したループの実行性能を向上させることができます。

「図 4.18 temp 指示子のないプログラム例」の場合は、変数 t がループの中でしか使用されていなくても、t が外部変数であるため、本処理系は t が関数 func の中で参照されていると判断し、t の値が正しくなるようなループスライスを行います。

図 4.18 temp 指示子のないプログラム例

この場合、ループの終了時の t の値が、関数 func の中で参照されないことが分かるのであれば、「図 4.19 temp 指示子の使用例」のように temp で t を指定します。これにより、ループ終了時の t の値を正しくする命令が不要になるので、実行性能が向上します。

図 4.19 temp 指示子の使用例

int t;main(){

・・・

for(j=0; j<50; j++){ for(i=0; i<1000; i++){ t = a[j][i] + b[j][i]; c[j][i] = t + d[j][i]; } }

・・・

func();}

並列動作

int t;main(){

・・・

#pragma loop temp t for(j=0; j<50; j++){ for(i=0; i<1000; i++){ t = a[j][i] + b[j][i]; c[j][i] = t + d[j][i]; } }

・・・

func();}

並列動作

51

C++ 言語使用手引書

注意事項temp 指示子に、一時的に使用されている変数以外の変数を誤って指定した場合、本処理系は誤ったループスライスを行うことがあります。

independent 指示子independent指示子は、ループ内の関数を引用しても逐次実行のときと動作が変わらないことを、本処理系に指示します。これにより、関数の引用のあるループをループスライスの対象にします。independent 指示子にはループスライスに影響しない関数名を指定できます。また、関数名を省略すると、対象範囲内のすべての関数に有効となります。independent 指示子に指定した関数は、-Kparallel を指定して翻訳しなければなりません。

「図 4.20 independent 指示子のないループの例」の場合、関数 func を引用しているため、本処理系はループがループスライス可能であるかどうか判断できません。

図 4.20 independent 指示子のないループの例

もし関数funcの引用のあるループをループスライスしても、実行結果に影響を与えないと分かっているのであれば、「図 4.21 independent 指示子の使用例」のように independent を使用することにより、このループはループスライスされます。

図 4.21 independent 指示子の使用例

注意事項

#include <math.h>main(){ double a[10000],j; double func(double); for(i=0; i<10000; i++){ j = 1; a[i] = func(j); }

・・・

}double func(double j){ return sqrt(pow(j,2) + 3*j + 6);}

#include <math.h>main(){ double a[10000],j; double func(double);#pragma loop independent func for(i=0; i<10000; i++){ j = 1; a[i] = func(j); }

・・・

}double func(double j){ return sqrt(pow(j,2) + 3*j + 6);}

並列動作

52

第 4 章 並列化機能

independent 指示子に、ループスライス不可能な手続きを誤って指定した場合、本処理系は誤ったループスライスを行うことがあります。なお、ループスライス不可能な手続きの例として、以下のようなループがあります。・ 手続き間で依存関係がある手続き

reduction 指示子reduction 指示子は、リダクション演算が含まれるループを並列化することを、本処理系に指示します。

「図 4.22 reduction 指示子の使用例」の場合、-Kreduction を指定しなくても、reduction 指示子を指定することにより、リダクション演算を含むループを並列化することができます。

図 4.22 reduction 指示子の使用例

noreduction 指示子noreduction 指示子は、リダクション演算が含まれるループを並列化しないことを、本処理系に指示します。

「図 4.23 noreduction 指示子の使用例」の場合、noreduction 指示子を指定することにより、リダクション演算を含むループの並列化を抑止することができます。

図 4.23 noreduction 指示子の使用例

4.2.3.3 自動並列化機能を使うときの留意事項本処理系の自動並列化機能を使用する場合の留意事項について説明します。

4.2.3.3.1 並列処理の入れ子での注意ループスライスされたループ内で関数を引用していて、引用先の関数中にループスライスされるループを含む場合、結果的に並列実行部分が入れ子になります。このような場合、内側のループは逐次実行されます。このようなループを含むソースプログラムは -Kparallel,instance=N を指定して翻訳してはなりません。

#pragma loop reduction for(i=0; i<5000; i++){ s = s + a[i]; }

並列動作

#pragma loop noreduction for(i=0; i<5000; i++){ s = s + a[i]; }

逐次動作

53

C++ 言語使用手引書

「図 4.24 並列処理が入れ子になった場合」に、スライスされたループが逐次実行される例を示します。このようなループを含むソースプログラムを -Kparallel,instance=N を指定して翻訳すると、実行結果は保証されません。

図 4.24 並列処理が入れ子になった場合

a.cc のソースプログラムを以下のように翻訳した場合、実行結果は保証できません。$ FCC -Kparallel,instance=4 a.cc(誤った使い方)

このような誤りを防ぐために、ループスライスされるループ内で引用している関数に、serial指示子を以下のように指定します。

4.2.3.3.2 -Kparallel,reduction 指定時の注意-Kparallel,reduction を指定して翻訳したとき、並列実行の結果が、逐次実行の結果と異なることがあります。これは、並列実行のときの演算順序が、逐次実行の演算順序と異なる場合があるためです。

「図 4.25 リダクションによる精度差」は、「4.2.3.1.6 リダクションによるループスライス」の説明で使用した例です。変数 sum は、逐次実行では、配列要素 a[0] から a[9999] まで順次に加

#include <stdio.h>#define M 4000double a[M][M];void f1(int);void f2(int);

main(){ f1(M); printf("%e\n",a[0][0]); }

void f1(int n){ int i;#pragma loop independent for(i=0; i<n; i++){ f2(i); }}

void f2(int i){ int j; for(j=0; j<i+1; j++){ a[i][j] = 3.8; }}

このループは並列実行される

このループは逐次実行される

#pragma procedure serial

void f2(int i){ int j; for(j=0; j<i+1; j++){ a[i][j] = 3.8; }}

逐次化

54

第 4 章 並列化機能

算されます。並列実行では、配列要素 a[0] から a[4999] まで順次に加算した値を変数 sum1 として、配列要素 a[5000] から a[9999] まで加算した値を sum2 とします。そして、sum1 と sum2 を加算した値を sum とします。つまり、逐次実行と並列実行では、配列 A の要素の値を累計する順番が違うので、演算結果に精度差が生じることがあります。

図 4.25 リダクションによる精度差

4.2.3.3.3 適化制御行の使い方の注意本処理系は、 適化指示子の使い方が誤っている場合、誤ったループスライスを行います。disjoint 指示子、temp 指示子または independent 指示子の誤った使い方を、以下に示します。

以下のプログラムは、配列 a に対して、誤った disjoint 指示子を指定しています。ループスライスを行うと配列 a の定義引用順序が変わるため、誤った動作をすることがあります。

以下のプログラムは、変数 t に対して、誤って temp 指示子を指定しています。ループの実行後、変数 t の値は保証されないので、変数 last に期待した値が代入されないことがあります。

sum = 0;for(i=0; i<10000; i++){ sum = sum + a[i];}

sum1 = 0;for(i=0; i<5000; i++){ sum1 = sum1 + a[i];}

sum2 = 0;for(i=5000; i<10000; i++){ sum2 = sum2 + a[i];}

sum = sum + sum1 + sum2;

#pragma loop disjoint a

for(i=1; i<10000; i++){ a[i] = a[i-1] + b[i];}

#pragma loop temp t

for(i=0; i<1000; i++){ t = a[i] + b[i]; c[i] = t + d[i];}last = t;

55

C++ 言語使用手引書

以下のプログラムは、関数 func に対して、誤って independent 指示子を指定しています。関数funcの引用によって配列aの定義・引用の順序が変わるため、結果が正しくない場合があります。

4.2.3.3.4 並列処理中の標準関数ループスライスされたループ内で関数を引用していて、引用先の関数中にループスライスの対象とならない標準関数を含む場合、動作は保証されません。並列実行に伴うオーバヘッドのため、逐次処理した場合より実行性能が低下する場合があります。

4.2.3.3.5 C++ プログラムにおける注意以下の条件に適合するようなループは、自動並列化機能の対象とならない場合があります。・ 例外処理を含んだ関数内のループ・ コンストラクタおよびデストラクタ内のループ・ 仮想関数内で #pragma(global|procedure|loop)temp により指定された範囲内のループまた、コンストラクタ、デストラクタから呼び出された関数内に並列化対象となるループがあった場合、または、大域の operator new または operator delete 内に並列化対象となるループがあった場合、実行時異常となる場合があります。

4.3 OpenMP 仕様による並列化

ここでは、本処理系で提供している OpenMP 仕様による並列化について説明します。本処理系は、OpenMP Application Program Interface Version2.5(May 2005) にもとづいて記述されたプログラムを翻訳するコンパイラです。OpenMP Application Program Interface Version2.5(May 2005) については、以下の URL をお読みください。

http://www.openmp.org

4.3.1 翻訳・実行の方法ここでは、OpenMP 仕様で記述されたソースプログラムの翻訳および実行の方法について説明します。

4.3.1.1 翻訳の方法ソースプログラムの翻訳および結合編集を行うには、翻訳時オプション -KOMP を指定します。

4.3.1.1.1 OpenMP プログラムを翻訳するための翻訳時オプションここでは、OpenMP プログラムを翻訳するための翻訳時オプションについて説明します。

-KOMP

int a[1000],b[1000];#pragma procedure independent func

main(){ int i; void func(int); for(i=1; i<1000; i++){ a[i] = b[i] + 1; func(i-1); }}

void func(int j){ a[j] = a[j] + 1;}

56

第 4 章 並列化機能

-KOMP は、OpenMP 仕様の指示子を有効にし、ソースプログラムを翻訳します。-KOMP は、結合編集時にも指定する必要があります。-KOMP を指定して翻訳されたオブジェクトプログラムが含まれる場合は、結合編集時に -KOMP を指定する必要があります。

例:$ FCC a.cc -KOMP -c$ FCC a.o -KOMP

4.3.1.1.2 OpenMP プログラムの 適化情報を表示するための翻訳時オプションここでは、OpenMP プログラムの 適化情報を表示するための翻訳時オプションについて説明します。

-Ksrc-KOMP と -Ksrc が同時に指定された場合、OpenMP 仕様のディレクティブによって指示された実行文に対する並列化情報の表示は、以下のようになります。

・ 並列に実行される可能性がある文に対しては、p が表示されます。冗長に実行される文に対しては、表示されません。for 指示構文または sections 指示構文に直接囲まれた実行文がこれに該当します。

・ 同時に 1 スレッドだけで実行される文に対しては、s が表示されます。master 指示構文、single 指示構文、critical 指示構文または ordered 指示構文に直接囲まれた実行文がこれに該当します。atomic 指示構文の直後の実行文に対しては、その全体が排他的に 1 スレッドで実行される場合、s が表示されます。

・ 一つの実行文の中で、並列に実行される可能性がある部分と、1 スレッドだけで実行される部分が混在している場合、m が表示されます。

ネストした並列実行では、その実行文を囲む も内側のパラレルリージョンに対する並列化情報を表示します。そのパラレルリージョンがどのように呼ばれるか(並列実行中に呼ばれるか、それとも逐次実行中に呼ばれるか)は、表示に影響を与えません。

4.3.1.2 実行の方法OpenMP プログラムを実行させる手続きは、逐次実行のときと同じです。

4.3.1.2.1 実行時の環境変数

FLIB_SPINWAIT環境変数 FLIB_SPINWAIT で、同期待ち処理を調節することができます。デフォルトは unlimitedです。unlimited: 同期が獲得できるまでスピン待ちを行います。0: スピン待ちを行わず、サスペンド待ちを行います。<n>s:n 秒間スピン待ちし、その後サスペンド待ちに移ります。<n>ms:n ミリ秒間スピン待ちし、その後サスペンド待ちに移ります。

ここで、<n> は 0 以上の整数。スピン待ちとは、スレッド間で同期を待ち合うとき、CPU 時間を消費する方法で待たせる方式です。逆に、サスペンド待ちは CPU 時間を消費せずに待たせます。スピン待ちを行う方が並列処理のオーバヘッドが少ないため、経過時間を重視する場合には、unlimited を選択してください。CPU 時間を重視する場合は、0 を選択してください。

FLIB_FASTOMP環境変数 FLIB_FASTOMP に TRUE を設定することにより、利用者は高速実行時ライブラリを使用することができます。デフォルトでは高速実行時ライブラリは使用されません。高速実行時ライブラリは、以下のような特徴を持ちます。

・ ネストした並列化がないことと、スレッドが CPU に一対一に対応付けられていることを前提とすることにより、高速化を図っています。

・ Parallelnavi 環境では、高速なハードウェアバリアを使用することができます。

ただし、高速実行時ライブラリを使用できるプログラムには、以下の制限があります。

57

C++ 言語使用手引書

・ num_threads節およびomp_set_num_threads関数で指定するスレッド数は、実行時環境によって決まるスレッド数と一致していなければなりません。

実行時環境によって決まるスレッド数は、「4.3.1.2.3 実行時の注意事項」(Parallelnavi 環境の場合には、「付録 C Parallelnavi」)をお読みください。高速実行時ライブラリを使用するとき、OpenMP 仕様の環境変数と OpenMP 仕様による実行の制御は、以下のように制限を受けます。

・ 環境変数OMP_NESTEDとomp_set_nested関数による設定に関わらず、ネストしたパラレルリージョンは常に逐次化されます。

・ 環境変数 OMP_DYNAMIC と omp_set_dynamic 関数による設定に関わらず、スレッド数は使用可能な CPU 数を超えることはできません。

使用可能な CPU 数については、「4.3.1.2.3 実行時の注意事項」(Parallelnavi 環境の場合には「付録 C Parallelnavi」)をお読みください。

THREAD_STACK_SIZE (1 ≦ THREAD_STACK_SIZE ≦ 2147483647)利用者は、環境変数 THREAD_STACK_SIZE の値として、スレッド毎のスタック領域の大きさを K バイト単位で指定することができます。詳細については、「4.3.1.2.3 実行時の注意事項」をお読みください。

4.3.1.2.2 OpenMP 仕様の環境変数利用者は、以下の OpenMP 仕様の環境変数を使用することが可能です。OpenMP 仕様の環境変数の詳細については、OpenMP 仕様書をお読みください。

OMP_SCHEDULEschedule 節に runtime を持つ、for 指示子または parallel for 指示子に対して、実行すべきスケジュールの種類と chunk_size を指定します。

OMP_NUM_THREADS実行中に使用するスレッドの数を指定します。

OMP_DYNAMIC動的スレッド調整機能の有効または無効を指定します。

OMP_NESTEDパラレルリージョンのネスト機能の有効または無効を指定します。

4.3.1.2.3 実行時の注意事項本処理系の OpenMP 仕様による並列化機能を使用する場合の注意事項を、以下に示します。

実行時の変数割付け本処理系の OpenMP 仕様による並列化機能を使用したプログラムは、関数内でローカルな変数および private 変数をスタック領域に割り付けます。関数内でローカルな変数および private 変数に必要な領域が巨大な場合には、スタック領域を十分な大きさに拡張する必要があります。プロセスのスタック領域の制限値は、limit(1) コマンドで、設定が可能です。スレッド毎のスタック領域は、プロセスのスタック領域と同じ大きさで確保されます。ただし、プロセスのスタック領域の制限値が、使用可能な実装メモリと仮想メモリの大きさの小さい方をスレッド数で割った値より大きい場合、本システムがスレッド毎のスタック領域の大きさを次のように、仮定して確保します。なお、仮想メモリの大きさとは、limit(1) コマンドの仮想記憶の 大サイズとして表示される値です。S = ( M/T ) / 5S:スレッド毎のスタック領域の大きさ(byte)M:実装メモリと仮想メモリの小さい方の大きさ(byte)T:スレッド数

スレッド毎のスタック領域の大きさを、特定の大きさで確保したい場合には、環境変数THREAD_STACK_SIZE を使用してください。環境変数 THREAD_STACK_SIZE については、「4.3.1.2.1 実行時の環境変数」をお読みください。

CPU 数の上限

58

第 4 章 並列化機能

以下の値を、CPU 数の上限値とします。

・ Solaris プロセッサセットが定義されている場合

プロセッサセット内では、プロセッサセットの CPU 数プロセッサセット外では、システムの CPU 数

・ Solaris プロセッサセットが定義されていない場合

システムの CPU 数

スレッド数並列実行のスレッド数は、高速実行時ライブラリを使用するとき OpenMP と自動並列化で共通となり、そうでないときそれぞれ独立に決定されます。高速実行時ライブラリの使用は、環境変数FLIB_FASTOMP の設定によって制御することができます。詳細は、「4.3.1.2.1 実行時の環境変数」をお読みください。

高速実行時ライブラリを使用するとき(FLIB_FASTOMP が TRUE のとき)スレッド数は以下の優先順位で決定されます。

1.環境変数 OMP_NUM_THREADS の指定値注

2.環境変数 PARALLEL の指定値3.Solaris プロセッサセットの CPU 数4.1

この優先順位で決まるスレッド数が CPU 数の上限値を超えるとき、スレッド数は CPU 数の上限値となります。num_threads 節および omp_set_num_threads 関数によって指定する値は、ここで決まるスレッド数と一致していなければなりません。異なる値を指定した場合には、プログラムの実行が終了されます。この時に、環境変数 FLIB_C_MESSAGE が存在する場合には mpc1041i-s のメッセージが出力されます。

高速実行時ライブラリを使用しないとき(FLIB_FASTOMP が TRUE でないとき)OpenMP のスレッド数は、以下の優先順位で決定されます。自動並列化のスレッド数は、「4.2自動並列化」の記述に従います。1.parallel 指示子の num_threads 節の指定値2.omp_set_num_threads 関数の指定値3.環境変数 OMP_NUM_THREADS の指定値4.環境変数 PARALLEL の指定値5.Solaris プロセッサセットの CPU 数6.1

動的スレッド調整機構が有効な場合には、この優先順位で決まるスレッド数が CPU 数の上限値を超えるとき、スレッド数は CPU 数の上限値になります。動的スレッド調整機構が無効な場合、1CPU 当たりのスレッド数が 1 を超える場合には、並列に実行されることを意図したスレッドが時分割で実行されることになります。このような場合、スレッド間の同期処理のオーバヘッドが大きくなり、実行性能が低下することがあります。システムによる負荷も考慮して、1CPU 当たりのスレッド数が 1 以下になるようにスレッド数を設定することをお勧めします。

なお、Parallelnavi 環境下で実行する場合のスレッド数については、「付録 C Parallelnavi」をお読みください。

4.3.1.2.4 複数のスレッドからの出力情報プログラムの実行時に同一プログラム内で複数のスレッドからエラーが検出された場合、トレースバックマップは、スレッド単位に出力されます。したがって、パラレルリージョン内では、スレッド数分の情報が出力されます。

注 .結合編集時に -Kparallel が指定されているとき、環境変数 PARALLEL の指定値があれば、その値と一致していなければなりません。一致していない場合には小さい方の値が採用されます。この時に、環境変数 FLIB_C_MESSAGE が存在する場合には mpc1042i-w のメッセージが出力されます。

59

C++ 言語使用手引書

4.3.2 処理系依存の仕様OpenMP 仕様において、処理系の実現に任されている仕様については、本処理系では以下のように実現しています。各項目の詳細については、OpenMP 仕様書をお読みください。

メモリモデル4 バイトを超えるか 4 バイト境界を跨ぐ変数に対して、2 つのスレッドからの書き込みが同時に起こるとき、明示的な排他制御が行われなければ、変数の値はどちらの値にもならず不定となることがあります。4 バイトを超えるか 4 バイト境界を跨ぐ変数に対して、2 つのスレッドから書き込みと読み出しが同時に起こるとき、明示的な排他制御が行われなければ、読み出される変数の値は書き込み前の値でも書き込み後の値でもなく不定となることがあります。

内部制御変数以下の環境変数またはライブラリルーチンによって設定される値は、それぞれ内部制御変数に格納されます。内部制御変数は、全スレッドで共有されます。

・ OMP_NUM_THREADS または omp_set_num_threads()

・ OMP_DYNAMIC または omp_set_dynamic()

・ OMP_NESTED または omp_set_nested()

・ OMP_SCHEDULE

パラレルリージョンのネスト機能本処理系の OpenMP 仕様による並列化機能では、ネスト並列化機能を実現しています。システムで使用できるスレッドの数やスタック領域などの資源が許す限り、ネストのレベルに上限はありません。ただし、環境変数 FLIB_FASTOMP に TRUE が設定されている場合には、ネスト並列は抑止されます。

動的スレッド調整機能本処理系の OpenMP 仕様による並列化機能では、動的スレッド調整機能を実現しています。この機能の効果は、「4.3.1.2.3 実行時の注意事項」をお読みください。デフォルトの状態では、動的スレッド調整機能は有効です。

スレッド数スレッド数については、「4.3.1.2.3 実行時の注意事項」をお読みください。

schedule 節本処理系の OpenMP 仕様による並列化機能では、schedule 節が省略された場合、デフォルトは

“schedule(static)”となります。

環境変数 OMP_SCHEDULE本処理系の OpenMP 仕様による並列化機能では、スケジュールタイプが runtime の for 指示子に対して、環境変数OMP_SCHEDULEが省略された場合、デフォルトは“schedule(static)”となります。

sections 構文スレッドは、sections 領域に到達するか、その中の一つの section 領域の実行を終了したとき、その順序で次の section 構文と対応付けられます。

single 構文single 領域は、 初にその領域に到達したスレッドによって実行されます。

atomic 構文複数の atomic 領域が同時に実行されるとき、すべてが排他的に実行されます。

実行時ライブラリルーチンと環境変数引数に 0 以下の値を与えて omp_set_num_threads ルーチンを呼び出すと、何の効果もありません。環境変数 OMP_NUM_THREADS に 0 以下の値を設定すると、1 を設定した場合と同じ効果をもちます。これらの値として、システムがサポートするスレッド数を超える数値を設定してはなりません。

60

第 4 章 並列化機能

活動状態のparallel領域の中で、omp_set_num_threads、omp_set_dynamicまたはomp_set_nestedルーチンを呼び出してはなりません。活動状態のparallel領域の中で、omp_get_max_threads、omp_get_dynamicおよびomp_set_nestedルーチンに結合するスレッドは、遭遇するスレッドです。

4.3.3 プログラミングの注意事項ここでは、OpenMP 仕様のプログラミングにおける注意事項について説明します。

4.3.3.1 パラレルリージョンの実現パラレルリージョンの静的範囲は、翻訳処理により、内部関数化されます。生成された関数名は、“.OMP_ 通し番号”という名前が付加されます。

4.3.3.2 OpenMP プログラムの自動並列化-KOMP と -Kparallel は、同時に指定可能です。同時に指定した場合、自動並列化されるループは以下のように制限されます。

・ OpenMP のパラレルリージョンの静的範囲内にあるループは、自動並列化の対象とはなりません。

・ OpenMP 指示子を静的に内部に含むループは、自動並列化の対象とはなりません。

・ OpenMP 指示子で並列化されるループがある場合、以下のループは自動並列化の対象とはなりません。

OpenMP 指示子で並列化されるループ自身 OpenMP 指示子で並列化されるループの内側にあるループ

4.3.3.3 OpenMP 指示子コンストラクタ、デストラクタ、operator new()、operator delete() 内に OpenMP 指示子を指定した場合、正しく動作しない場合があります。

4.3.4 他のマルチスレッドプログラムとの結合OpenMP プログラム以外の、マルチスレッドプログラムのオブジェクトプログラムとの結合について、制限事項を示します。

本処理系の自動並列化プログラム本処理系で-Kparallelを指定して作成した自動並列化プログラムのオブジェクトプログラムは、本処理系で -KOMP を指定して作成したオブジェクトプログラムと結合可能です。

4.3.5 OpenMP プログラムのデバッグ実行可能プログラムでエラーが発生したとき、異常終了したとき、または利用者が目的とした結果を得られないときは、その原因を追求し、ソースプログラムの修正を行う必要があります。fdb は、マルチスレッドプログラムに対応したシンボリック・デバッガです。fdb を利用してOpenMP プログラムのデバッグが可能です。ただし、Solaris 10 OS 上でプログラムのデバッグをする場合は、マスタスレッドのみ可能です。詳細は、fdb コマンドの man マニュアルをお読みください。

4.3.6 並列実行情報並列実行情報は、プログラムの実行環境、プログラムが並列で実行されている割合などを示します。また、パラレルリージョンごとの実行時間から、並列の効果などを知ることができます。

4.3.6.1 並列実行情報として出力される情報並列実行情報として出力される情報を、以下に示します。

++=======================================++ || PARALLEL EXECUTION INFORMATION || ++=======================================++

61

C++ 言語使用手引書

+--------------------+--------------------+ | Number of CPU(s) | 2 | +--------------------+--------------------+ | Number of thread(s) | +--------------------+--------------------+-------------------+-------------------+ | Automatic | | | | | Parallelization | 2 | OpenMP | 2 | +--------------------+--------------------+-------------------+-------------------+ | Execution mode information | +--------------------+--------------------+-------------------+-------------------+ | FLIB_FASTOMP | FALSE | FLIB_SPINWAIT | SPIN MODE | +--------------------+--------------------+-------------------+-------------------+ | Memory Information | +--------------------+--------------------+-------------------+-------------------+ | Largepage | disable | Thread stack size | 8388608 | +--------------------+--------------------+-------------------+-------------------+ |Barrier Information | +--------------------+--------------------+ | Barrier kind | Softbarrier | +--------------------+--------------------+

環境変数 FLIB_PARALLEL_INFO に 1 を指定した場合、以下の情報が出力されます。

Number of CPU(s)使用可能な CPU 数。

Number of thread(s)自動並列および OpenMP で使用したスレッド数。

Execution mode information環境変数 FLIB_FASTOMP( 高速ライブラリ使用の有無 ) の設定、FLIB_SPINWAIT( 待機スレッドの処理が SPIN MODE であるか、SUSPEND MODE であるか ) の設定。

Memory Informationラージページ機能の使用の有無、および全スレッドで獲得したスレッドスタックの総量。

Barrier Information使用されたバリア種別。

環境変数 FLIB_PARALLEL_INFO に 2 を指定した場合、1 で出力される情報に加えて、以下の情報が出力されます。

Barrier number of times自動並列および OpenMP のバリア同期回数。

The parallelization number of times自動並列および OpenMP で並列化された回数。

The percentage of parallel region for master threadプログラムが並列で実行している割合。" マスタスレッドのパラレルリージョン実行時間 ÷ real time"。

The percentage of parallel region for all thread逐次プログラムからの並列化率の目安。"全スレッドのパラレルリージョン実行時間の合計 ÷ (全スレッドのパラレルリージョン実行時間の合計 + マスタスレッドの逐次リージョン実行時間 )"。

Parallel region information of Automatic Parallelization自動並列化されたパラレルリージョンの手続き名、アドレス、実行時間およびパラレルリージョンのコスト分布一覧。ただし、Fortran と結合した場合、アドレスは表示されません。

Parallel region information of OpenMPOpenMP で並列化されたパラレルリージョンの手続き名、アドレス、実行時間およびパラレルリージョンのコスト分布一覧。ただし、Fortran と結合した場合、アドレスは表示されません。(OpenMP のネストされた並列実行は含みません。)

62

第 5章 出力情報

ここでは、C++ 言語で記述されたプログラムの翻訳および実行において、本処理系が出力する情報について説明します。

5.1 翻訳時情報

ここでは、C++ 言語で記述されたプログラムの翻訳において、本処理系が出力する情報について説明します。

5.1.1 ヘッダ翻訳時オプション -Ksrc または -Ksta のうち少なくとも 1 つが指定された場合、翻訳時に出力する各情報に対して「図 5.1 ヘッダの出力形式」のようにヘッダを出力します。

図 5.1 ヘッダの出力形式

5.1.2 ソースリストソースリストを標準出力ファイルに出力することができます。並列翻訳した場合、以下のオプションに従って、ソースリスト上に並列化表示記号が付加されて出力されます。

・ -Ksrc

並列化表示ソースリストを出力します。

・ 省略時

並列化表示ソースリストを出力しません。並列化表示ソースリストの例を「図 5.2 並列化表示の出力例」に示します。この例では、7 行目の for 文に含まれる文が並列化されたことを示しています。

Fujitsu C/C++ Version バージョン 日付

バージョン : コンパイラのバージョンを出力します。日付:翻訳した日を asctime 関数の形式で出力します。

63

C++ 言語使用手引書

図 5.2 並列化表示の出力例

並列化表示ソースリストで、並列化および 適化の表示は、行位置と文の間に次の記号で示されます。

並列化の表示記号 並列化の表示記号は、次の条件で出力します。

・ for 文、while 文、do-while 文または if-goto 文のループ制御文のある行では、ループ制御文に対する表示記号を出力します。

・ 複数のループ制御文がある行では、一番左にあるループ制御文に対する表示記号を出力します。

並列化の表示記号には、以下に示すループ制御文に対する表示記号とループ制御文以外の文に対する表示記号があります。

for 文、while 文または do-while 文に対する表示記号p : 並列化されたことを示します。m : 並列化された部分とされなかった部分があることを示します。s : 並列化されなかったことを示します。空白 : 並列化対象ループでないことを示します。

for 文、while 文または do-while 文以外に対する表示記号p : 並列化されたことを示します。

ただし、for 文、while 文または do-while 文に対する表示記号が s の場合、コンパイラは並列化効果が得られないと判断し、並列化を行いませんが、並列化可能であったことを意味します。

m : 並列化された部分とされなかった部分があることを示します。ただし、for 文、while 文または do-while 文に対する表示記号が s の場合、コンパイ

Compilation information Current directory : ディレクトリ名 Source file : ソース名(line-no.)(optimize) 1 #include <stdio.h> 2 float sub(int i); 3 int main(){ 4 int i; 5 float a[1000]; 6 7 p for(i=0; i<1000; i++){ 8 p a[i] = i; 9 p } 10 11 printf("%lf \n", a[0]); 12 13 s for(i=0; i<1000; i++){ 14 s a[i] = sub(i); 15 s } 16 17 printf("%lf \n", a[0]); 18 } 19 20 float sub(int j){ 21 return (float)j; 22 }

64

第 5 章 出力情報

ラは並列化効果が得られないと判断し、並列化を行いませんが、並列化可能であった部分と不可能であった部分があったことを意味します。

s : 並列化されなかったことを示します。空白 : 並列化対象ループでないことを示します。

適化の表示記号適化の表示記号には、以下に示す表示記号があります。u : ループ・アンローリングされたことを示します。i : 関数呼出しがその位置にインライン展開されたことを示します。

ループ・アンローリングによって展開された文と関数呼出しがインライン展開された文が同一の行にある場合、"u" を表示します。

ループ・アンローリングの出力例を「図 5.3 ループ・アンローリングの出力例」に示します。この例では、行番号 7 のループに含まれる文がループ・アンローリングされています。

図 5.3 ループ・アンローリングの出力例

5.1.3 並列化メッセージ並列化メッセージは、並列化できなかった原因、またはどのように並列化および 適化されたかを示します。-Kpmsg を指定することで、並列化メッセージを標準エラー出力に出力することができます。

「図 5.2 並列化表示の出力例」で使用したプログラムでは、-Kparallel を指定した場合、「図 5.4並列化メッセージの出力例」に示すメッセージが出力されます。

図 5.4 並列化メッセージの出力例

5.1.4 統計情報以下のオプションにより、統計情報を標準出力ファイルに出力することができます。

・ -Ksta

統計情報を出力します。

・ 省略時

統計情報を出力しません。統計情報で表示するのは、有効な 適化関連オプションだけです。したがって、表示されていない 適化関連オプションは無効であることを意味します。

5.1.4.1 表示形式プログラム単位の統計情報を「図 5.5 統計情報の出力形式」の形式で出力します。

図 5.5 統計情報の出力形式

(line-no.)(optimize) ... 7 p u for(i=0; i<1000; i++){ 8 p u a[i] = i; 9 p }

Parallelization messages "a.c", line 7: このループはループ変数 i で並列化されました。 "a.c", line 14: ループ内に自動並列化の制約となる手続引用が存在します。

Statistics information Options : 有効な 適化関連オプションの一覧

65

C++ 言語使用手引書

5.1.4.2 表示対象外のオプション統計情報では、 適化関連のオプションを表示対象としています。ld 関連オプションなどは表示対象外です。

・ 表示対象外のオプション

-# / -### / -A- / -Aname[(tokens)] / -Bc / -C / -c / -dc / -Dname[=tokens] / -E / -G / -H / -Idir / -Ldir / -lname / -opathname / -P / -Rdir / -S / -Uname / -Wtool,arg1[,arg2,...] / -Yitem,dir / --ar / メッセージ関連オプション (-w 以外 ) / 言語仕様関連オプション / PCH 関連オプション

5.1.4.3 コンパイラが解釈して表示するオプション以下のオプションは、統計情報にそのままでは表示されません。ご注意ください。-Keopt : -Keval と -Kpreex に分解して表示-KGREG : -KGREG_APPLI と -KGREG_SYSTEM に分解して表示-Kfast : 誘導されるオプションで表示-Kfast_GP[={0|1|2}] : 誘導されるオプションで表示-Kfast_GP2[={0|1|2}] : 誘導されるオプションで表示-Kfast_VI[={0|1|2|3}] : 誘導されるオプションで表示-KV8PFMADD : -KV8PLUS と -KFMADD に分解して表示-KV9FMADD : -KV9 と -KFMADD に分解して表示

5.2 実行時情報

ここでは、C++ 言語で記述されたプログラムの実行において、本処理系が出力する情報について説明します。

5.2.1 トレースバック情報環境変数 MPCL に trace が指定されており、ユーザプログラムの並列実行時にエラーが発生した場合、トレースバックマップを標準エラー出力へ出力します。この機能により、主プログラムからエラーが発生したプログラム単位までの呼出し関係を知ることができます。主プログラムからエラーが発生したプログラム単位までの呼出し関係を、「図 5.6 トレースバックマップの出力形式」の形式で出力します。 なお、標準関数または数学関数でエラーが発生した場合、標準関数または数学関数を呼び出したプログラム名からの呼出し関係が表示されることがあります。

SIG : シグナルSIG_ID : 詳細コードf1 : エラーが発生したプログラム単位の入り口名または組込み関数名

fn : fn-1(n >1) を呼び出したプログラム単位の入り口名または組込み関数名

xxxxxxxx : エラーが発生した文の絶対番地 (16 進数表示 )yyyyyyyy : エラーが発生した文のプログラム単位の先頭からの相対番地 (16 進数表示 ) 組込み関数でエラーが発生した場合出力されません。s1 : エラーが発生した文の文番号 ただし、標準関数または数学関数でエラーが発生した場合出力されません。s2 : 各関数を呼び出している文の文番号 ただし、-Kline が有効でない場合出力されません。

The program was terminated abnormally with signal SIG.signal identifier = SIG_ID error occurs at f1 line s1 loc xxxxxxxx offset yyyyyyyy

f1 at loc xxxxxxxx called from loc xxxxxxxx in f2 line s2

f2 at loc xxxxxxxx called from loc xxxxxxxx in f3 f3 at loc xxxxxxxx called from loc xxxxxxxx in main line s2

main at loc xxxxxxxx called from o.s.

66

第 5 章 出力情報

図 5.6 トレースバックマップの出力形式

5.2.2 高速数学関数のエラー高速数学関数でエラーが発生した場合、各関数で定義されている値が復帰値として返されます。また、エラー番号に対応するエラー値が設定され、エラーメッセージが出力されます。高速数学関数は、エラーが発生すると必ず matherr 関数を呼び出します。したがって、利用者は、プログラム中に matherr という名前の関数を含めることによって、エラーの扱いを変更することができます。matherr のインタフェースについては、「図 5.7 高速数学関数エラーにおける処置例」をお読みください。数学関数のエラー条件、エラー発生時の復帰値、エラー番号に設定される値、matherr 関数に渡されるエラータイプ、およびエラーメッセージの出力の有無 ( エラーメッセージが出力される場合、そのメーセージの種類 ) を「表 5.1 高速数学関数のエラー処理」に示します。エラー番号に設定される値については、"man intro(2)" をお読みください。エラータイプについては、"man matherr(3M)" をお読みください。

表 5.1 高速数学関数のエラー処理

関数名 エラー条件復帰値

エラー番号 エラータイプメッセージ

-Xa -Xc -Xt -Xa -Xc -Xt

sin(x) |x| ≧ 3.53e+15

√ 0.5 ERANGE TLOSS TLOSS

cos(x) |x| ≧ 3.53e+15

√ 0.5 ERANGE TLOSS TLOSS

tan(x) |x| ≧ 3.53e+15

1.0 ERANGE TLOSS TLOSS

x が特異点 HUGE ERANGE SING -

asin(x) |x| > 1.0 0.0 EDOM DOMAIN 注1 - 注2

acos(x) |x| > 1.0 0.0 EDOM DOMAIN 注1 - 注2

atan2(x,y) x = y = 0.0 0.0 EDOM DOMAIN 注1 - 注2

sinh(x) x ≦ -709.782 -HUGE_VAL -HUGE ERANGE OVERFLOW 注1 - 注1

x ≧ 709.782 HUGE_VAL HUGE ERANGE OVERFLOW 注1 - 注1

cosh(x) |x|≧709.782 -HUGE_VAL -HUGE ERANGE OVERFLOW 注1 - 注1

exp(x) x ≦ -709.782 0.0 ERANGE OVERFLOW 注1 - 注1

x ≧ 709.782 HUGE_VAL HUGE ERANGE OVERFLOW 注1 - 注1

log10(x) x = 0.0 -HUGE_VAL -HUGE EDOM ERANGE EDOM DOMAIN SING 注1 - 注3

x < 0.0 -HUGE_VAL -HUGE EDOM DOMAIN 注1 - 注2

67

C++ 言語使用手引書

注1:エラーメッセージは出力されません。ただし、利用者定義の matherr 関数を作成することにより、エラーメッセージを出力可能です。

注2:DOMAIN のエラーメッセージが出力されます。また、利用者定義の matherr 関数を作成することにより、エラーメッセージを出力可能です。

注3:SING のエラーメッセージが出力されます。また、利用者定義の matherr 関数を作成することにより、エラーメッセージを出力可能です。

「図 5.7 高速数学関数エラーにおける処置例」では、asin 関数でエラーが発生したとき、復帰値として 0.0 を返すように matherr 関数を作成しています。

pow(x,y) x = 0.0,y < 0.0

-HUGE_VAL 0.0 EDOM DOMAIN 注1 - 注2

x = 0.0,y = 0.0

0.0 EDOM DOMAIN 注1 - 注2

x < 0.0,|y|≦MAXLONG

0.0 EDOM DOMAIN 注1 - 注2

アンダフロー 0.0 ERANGE UNDERFLOW 注1 - 注2

オーバフロー ± HUGE_VAL ±HUGE ERANGE OVERFLOW 注1 - 注2

gamma(x) x ≦ 0.0 HUGE_VAL HUGE EDOM SING 注1 - 注3

x ≧ 171.6243 HUGE_VAL HUGE ERANGE OVERFLOW 注1 - 注1

lgamma(x) x ≦ 0.0 HUGE_VAL HUGE EDOM SING 注1 - 注3

x >2.556348e+305

HUGE_VAL HUGE ERANGE OVERFLOW 注1 - 注1

hypot(x,y) オーバフロー HUGE_VAL ERANGE OVERFLOW - - -

scalb(x,y) アンダフロー 0.0 ERANGE UNDERFLOW 注1 - 注1

オーバフロー ± HUGE_VAL ±HUGE ERANGE OVERFLOW 注1 - 注1

log(x) x = 0.0 -HUGE_VAL -HUGE EDOM ERANGE EDOM DOMAIN SING 注1 - 注3

x < 0.0 -HUGE_VAL -HUGE EDOM DOMAIN 注1 - 注2

loglp(x) x = -1.0 -HUGE_VAL EDOM ERANGE EDOM DOMAIN SING 注1 - 注3

x < -1.0 -HUGE_VAL EDOM DOMAIN 注1 - 注2

表 5.1 高速数学関数のエラー処理

関数名 エラー条件復帰値

エラー番号 エラータイプメッセージ

-Xa -Xc -Xt -Xa -Xc -Xt

68

第 5 章 出力情報

図 5.7 高速数学関数エラーにおける処置例

#include <math.h>#include <string.h>main(){ double a[10] = {0.0,0.2,0.4,0.8,1.0,1.2,0.1,0.3,0.5,0.7 }; double b[10] ; int i; for(i=0;i<10;i++) b[i] = asin(a[i]);}

int matherr(struct exception *p){ if(p->type==DOMAIN && strcmp(p->name,"asin")==0){ p->retval=0.0; return(1); }else{ return(0); }}

69

C++ 言語使用手引書

70

第 6章 言語仕様

本章では、C++ 言語規格の言語仕様を元に、本処理系で拡張した言語仕様について説明します。

説明に入る前に、本章で使用する構文記法を説明します。構文要素(非終端記号)は、英数字を含む日本語で示し、リテラル語および文字集合の要素(終端記号)は英数字および特殊記号で示します。非終端記号に続くコロン (:) は、その後に非終端記号の定義があることを示します。選択可能な定義は、" 次のいずれか " と前置きしている場合を除き、別々の行に表示します。省略可能な記号は、添字 "opt" で示します。したがって、{ 式 opt} は、中括弧が省略可能な式を囲ん

でいることを示します。

6.1 long long 型

signed char、short int、int および long int の 4 つの符号付き整数型に加えて、long longint 型が追加されています。

接尾語整数接尾語:符号なし接尾語 長語接尾語opt

長語接尾語 符号なし接尾語opt

符号なし接尾語 長長語接尾語opt

長長語接尾語 符号なし接尾語opt

符号なし接尾語: 以下のいずれかu U

長長語接尾語:長語接尾語 長語接尾語

長語接尾語: 以下のいずれかl L

意味規則整数定数の型は、次の並びのうちでその値を表現できる 初の型とします。

接尾語なしの 10 進数 :int, long int, unsigned long int, long long int, unsigned long long int

接尾語なしの 8 進数または 16 進数 :int, unsigned int, long int, unsigned long int, long long int, unsigned long long int

文字 u または U が接尾語として付く場合 :unsigned int, unsigned long int, unsigned long long int

文字 l または L が接尾語として付く場合 :long int, unsigned long int, long long int, unsigned long long int

文字 u または U、および文字 l または L の両方が接尾語として付く場合 :unsigned long int, unsigned long long int

文字 l または L、および文字 l または L の両方が接尾語として付く場合 :long long int, unsigned long long int

型指定子としての制約型指定子の各並びは、以下の組のいずれか一つに属していなければなりません。一つの項目に二つ以上の組がある場合は、コンマで区切っています。型指定子はどんな順序で記述してもよく、また、ほかの宣言指定子と混在して記述することもできます。

・ long long, signed long long, long long int, signed long long int

・ unsigned long long, unsigned long long int

71

C++ 言語使用手引書

記述例 long long int lli=10LL; unsigned long long int ulli=10ULL;

6.2 pragma 指令

pragma 指令は、処理系への動作を指示します。

意味

#pragma 前処理字句列opt 改行

処理系に、以下の方法で動作することを指示します。

#pragma ident 文字列リテラル 改行文字列リテラル内の文字列を、オブジェクトプログラムの中に注釈として付加することを、処理系に指示します。これは、#ident 指令と同じ意味を持つ #pragma 指令です。一般に、オブジェクトプログラム中にバージョン管理情報を付加するために利用します。

#pragma weak 識別子 改行 識別子をウィーク・シンボルとして定義することを、処理系に指示します。

#pragma weak 識別子 1= 識別子 2 改行識別子 1 を識別子 2 と同じ値および型を持つウィーク・シンボルとして定義することを、処理系に指示します。

#pragma unknown_control_flow ( 識別子の並び ) 改行上記の形式の前処理指令は、識別子で指定された関数が処理系で認識できない制御の流れを持つことを、処理系に指示します。

#pragma int_to_unsigned 識別子 改行識別子で指定された関数が旧 C 言語では返却値が型 int を持っていることを、処理系に指示します。ただし、指定される関数の返却値は、型 unsigned でなければなりません。

#pragma redefine_extname < 旧関数名 > < 新関数名 > 改行オブジェクトコードの中の<旧関数名>である外部参照名をすべて<新関数名>に置き換えることを、処理系に指示します。

6.3 ident 指令

ident 指令は、C++ プログラムに注釈を付加することを指示します。

意味

# ident 文字列リテラル 改行指定した文字列リテラルがオブジェクトプログラムの ".comment セクション " に置かれます。".comment セクション " は、プログラムの実行時に記憶域にローディングされないセクションです。

# ident 前処理字句 改行指定した前処理字句が通常のテキストとして処理され、現在マクロ名として定義している各識別子は、その置換えの並びで置き換えられます。置換え後のすべての #ident 指令は、前の形式と一致しなければなりません。

6.4 assert 指令

assert 指令は、プレディケート名を定義し、アサーション字句をプレディケート名に関連付けることを指示します。

意味

# assert 識別子 アサーション指定子opt 改行

#assert 指令に続く識別子がプレディケート名であると定義します。また、プレディケート名に続くアサーション指定子の識別子の並びがアサーション字句であると定義します。

72

第 6 章 言語仕様

#assert 指令は、プレディケート名を定義し、アサーション字句をプレディケート名に関連付けます。識別子の並びのない #assert 指令は、対応する #unassert 指令を記述しているところまで有効です。

# 演算式の各識別子# 演算式の各識別子は、#assert 指令で指定したプレディケート名とアサーション字句にそれぞれ相当します。アサーション字句がプレディケート名に関連付けられている場合だけ 1 となり、その他の場合、0 となります。例えば、#system(unix) は 1 です。以下のアサーションは、処理系によってあらかじめ定義されています ( 既定義アサーション )。# assert system(unix) # assert machine(sparc) # assert cpu(sparc)

■記述例# assert langlevel(ansi) # assert langlevel(sysv) 上記の指令は、プレディケート名 langlevel を定義し、アサーション字句 ansi と sysv をプレディケート名に関連付けます。

# assert float上記の指令は、プレディケート名 float を定義します。アサーション字句は持ちません。

6.5 unassert 指令

unassert 指令は、プレディケート名とアサーション字句の関連付けを取り消すことを指示します。

意味

# unassert 識別子 アサーション指定子opt 改行

アサーション字句の関連付けを取り消します。識別子の並び ( アサーション指定子 ) がない#unassert 指令は、プレディケート名のアサーション字句の関連付けをすべて取り消します。指定した識別子がプレディケート名でない場合、#unassert 指令は無視されます。また、関連付けていないアサーション字句を指定した場合も、#unassert 指令は無視されます。

6.6 実装されていない言語仕様

本処理系で実装されていない言語仕様について説明します。・ ユニコードの表記方法 (\uabcd)・ テンプレートの export キーワード・ テンプレート名の遅延結合

73

C++ 言語使用手引書

74

第 7 章 言語間結合における注意事項

ここでは、C 言語または Fortran で書かれた関数との結合における注意事項を説明します。

7.1 C 言語との結合

C 言語で記述された関数を呼び出す場合、呼び出す関数を C 言語へのリンケージ指定 (extern"C") 付きで宣言する必要があります。また、C 言語で記述された関数から C++ で記述された関数を呼び出す場合、C 言語で書かれた関数を呼び出す場合と同様に、呼び出される関数を、C 言語へのリンケージ指定付きで宣言する必要があります。呼び出す関数の引数および復帰値の型として、C 言語で許されている型が指定できます。

7.2 Fortran との結合

Fortran で記述された関数も、C 言語で記述された関数と同様に、C 言語へのリンケージ指定(extern "C") 付きで宣言しておくことにより、呼び出すことができます。また Fortran 関数から C++ で記述された関数を呼び出す場合にも C 言語と同様にリンケージ指定しなければなりません。翻訳時には、--linkfortran の指定が必要です。その他の規則については、Fortran 使用手引書の言語間結合で説明している、C 言語と Fortranの言語間結合と同様です。

// C/C++ 間の関数の呼出し// C++ プログラムextern "C" { void cfunc(short int); int cpfunc(int);}int cpfunc(int i){ return i;}int main(){ cfunc(10); return 0;}

/* C プログラム */int cpfunc(int);void cfunc(short int si){ cpfunc(si);}

//Fortran/C++ 間の関数呼出し//C++ プログラムextern "C" { long int ffunc_ (long int *); long int cfunc_ (long int *);}long int cfunc_(long int *p){ return *p+1;}int MAIN__(){ long int j; long int i = 10; j = ffunc_ (&i); return (int)j;}

75

C++ 言語使用手引書

例! Fortran プログラムinteger function ffunc(x)integer::xinteger::cfuncffunc = cfunc(x)end

76

付録 A 高速数学関数

「付表 A.1 高速数学関数一覧」に、本処理系で提供する高速数学関数の一覧を示します。

付表 A.1 高速数学関数一覧

関数 機能

sin(x) 正弦を求めます。

cos(x) 余弦を求めます。

tan(x) 正接を求めます。

asin(x) 逆正弦を求めます。

acos(x) 逆余弦を求めます。

atan(x) 逆正接を求めます。

atan2(x,y) x/y の逆正接を求めます。

sinh(x) 双曲線正弦を求めます。

cosh(x) 双曲線余弦を求めます。

exp(x) 指数を求めます。

log10(x) 常用対数(底 10)を求めます。

pow(x,y) べき乗を求めます。

gamma(x) 対数ガンマ関数値を求めます。

lgamma(x)

hypot(x,y) ユークリッド距離を求めます。

scalb(x,y) x*pow(r,y) を求めます。(r=2)

log(x) 自然対数(底 e)を求めます。

log1p(x) 引数に 1.0 を加えた値の自然対数(底 e)を求めます。

77

C++ 言語使用手引書

78

付録 B 制限事項および注意事項

B.1 制限事項

本処理系には、以下の制限があります。ご注意ください。

B.1.1 OpenMP プログラムにおける制限

B.1.1.1 threadprivate 指示子threadprivate 指示子に、クラス型およびクラス配列型の変数を指定することはできません。

例 ) class A { public: int mem; A(){} ~A(){} }object; #pragma omp threadprivate(object) int main(){}

B.1.1.2 コンストラクタおよびデストラクタ内の OpenMP 指示子コンストラクタおよびデストラクタ内に、OpenMP 指示子を指定した場合、正しく動作しない場合があります。

例 ) class A { public: int mem; A(){ #pragma omp parallel mem++; } ~A(){ #pragma omp parallel mem--; } }object; int main(){}

B.1.2 OpenMP プログラムのデバッグ情報生成 (翻訳時オプション -g) における制限

B.1.2.1 メンバ関数を伴ったローカルクラスを含む関数メンバ関数を伴ったローカルクラスを含む関数内に、パラレルリージョンが指定されていた場合、パラレルリージョンに対する fdb を利用したデバッグを行うことができません。

例 ) int main(){ int a=0; class LOCAL_CLASS { public: void mem_func(){}; }; #pragma omp parallel { a++; } }

79

C++ 言語使用手引書

B.1.2.2 テンプレート関数テンプレート関数内に、パラレルリージョンが指定されていた場合、パラレルリージョンに対する fdb を使用したデバッグを行うことができません。

例 ) template <class T> void func(T x){ #pragma omp parallel { x++; } }; int main(){ func(0); }

B.1.2.3 パラレルリージョン内の例外処理パラレルリージョン内に例外処理が指定されていた場合、例外処理に対する fdb を使用したデバッグを行うことができません。

例 ) void func(){ throw 10; } int main(){ int i =100; #pragma omp parallel { try { func(); } catch (int){ i++; } } }

B.2 注意事項

ありません。

B.3 移行上の注意事項

B.3.1 -O4本処理系の -O4 は、C++ コンパイラ V4 系の製品の -O4 とは 適化項目が異なります。C++ コンパイラ V4 系の製品と同等の 適化を行いたい場合、-O3 -Klib -Keopt を指定してください。

B.3.2 -Kgs および -Kpreload本処理系は、-Kgs および -Kpreload をサポートしていません。従来の C++ コンパイラの -Kgs および -Kpreload と同等の 適化を行いたい場合、-O5 を指定してください。

B.3.3 -p本処理系は、-p をサポートしていません。プログラムをチューニングしたい場合、プログラミング支援ツール (Parallelnavi 環境 )、あるいは並列アナライザ ( 非 Parallelnavi 環境 ) をお使いください。

80

付録 B 制限事項および注意事項

B.3.4 ライブラリC++ コンパイラ V4 系の製品では、ISO 規格化以前の業界標準仕様ライブラリと標準 C++ ライブラリ(ISO準拠)が入っていますが、本製品では、標準C++ ライブラリだけの提供となっています。したがって、 V4 系の製品ではデフォルトとなる業界標準仕様ライブラリを使用して(--conform_libを指定しない)作成したオブジェクトプログラムと結合することはできません。その場合、旧資産のソースコードを再翻訳する必要があります。

B.3.5 非互換本製品では、C++ コンパイラ V4 系の製品と以下の非互換がありますので、使用にあたっては注意が必要です。

メンバ関数のフレンド宣言1) 内容メンバ関数のフレンド宣言において、そのメンバ関数に対するアクセス検査が行われます。

例 )class A { void f(); };class B { friend void A::f(); }; // Error: A::f not accessible from B

"tp.cc", line 2: エラー : 関数 "A::f" はアクセスできません。2) 対処方法フレンド宣言したメンバ関数のアクセス指定を修正してください。

テンプレート宣言1) 内容テンプレート宣言で指定されたテンプレートの引数と、定義されている型のチェックを行います。

例 )char K= 0;template <const void* p> struct S2 { static char m;};S2<&K> s61;main(){ s61.m = 10;}

"tp.cc", line 5: エラー : "char *" 型の引数は "const void *" 型のテンプレートパラメタと一致しません。

2) 対処方法テンプレートの引数を修正してください。

void 型でない関数の復帰値1) 内容void 型でない関数の復帰値がない場合、翻訳エラーとなります。

例 )long double d(){ return; /* error */}int main(){ d();}

"tp.cc", line 2: エラー : void でない 関数 "d" は値を返さなければなりません。2) 対処方法復帰値を指定してください。

81

C++ 言語使用手引書

B.4 環境変数の設定

B.4.1 コマンドの起動C++ コンパイラの起動コマンドである FCC を利用するためには、以下の設定が必要です。

・ 環境変数 PATH に ${INSTALL}/FSUNf90/bin を追加してください。

・ 環境変数 LD_LIBRARY_PATH に ${INSTALL}/FSUNf90/lib を追加してください。

・ 環境変数 LD_LIBRARY_PATH_64 に ${INSTALL}/FSUNf90/lib/sparcv9 を追加してください。

${INSTALL} は、インストール先のディレクトリです。

B.4.2 オンラインマニュアルオンラインマニュアル FCC(1) を利用するためには、以下の設定が必要です。

・ 環境変数 MANPATH に ${INSTALL}/FSUNf90/man を追加してください。

${INSTALL} は、インストール先のディレクトリです。

B.4.3 Tools.h++ の利用Tools.h++ を利用する場合は、--library=a または --library=t を指定する必要があります。

例 )$ FCC --library=a sample.cc

B.5 整合性

B.5.1 アプリケーションプログラムの整合性についてFCC コマンドが生成するオブジェクトプログラムは、サン・マイクロシステムズ社製 C++ コンパイラが生成するオブジェクトプログラムと互換がありません。Interstage と組み合わせて実行可能プログラムを作成することはできません。これは、Inter-stage が利用可能な C++ コンパイラを指定しているためです。

82

付録 C Parallelnavi

ここでは、Parallelnavi 環境における C++ プログラムの翻訳および実行について説明します。

C.1 ラージページ機能

Parallelnavi 環境では、ラージページ機能を利用することができます。ラージページ機能とは、ハードウェアがメモリを管理する単位である ' ページ ' を大きくし、実行性能を向上させる機能です。ラージページ機能の詳細は、「Parallelnavi 使用手引書」をお読みください。

C.1.1 翻訳ラージページ機能を利用するプログラムを作成するためには、翻訳時オプション -Klargepage を結合編集時に指定する必要があります。単にオブジェクトファイルを作成する場合にはこのオプションは必要ありません。したがって、一般のライブラリ等も通常どおり利用することができます。なお、-Klargepage が指定されない場合は、ラージページ機能に対応したプログラムは作成されません。-Klargepage には、ラージページ化レベルを指定することができます。

-Klargepage[={1|2}]-Klargepage=1 が指定された場合には、データ域およびヒープ域に対してラージページ機能を適用します。-Klargepage=2 が指定された場合には、データ域およびヒープ域に加えて、スタック域に対してもラージページ機能を適用します。-Kparallel または -KOMP と同時に指定した場合には、スレッド毎のスタック領域に対してもラージページ機能を適用します。ラージページ化されたスタック域は、通常のスタック域と異なり、ラージページ化されたヒープ域から、実行開始時に一括して獲得されます。

なお、実行時のプロセスのスタック領域の制限値が、使用可能なラージページメモリと仮想メモリの大きさの小さい方より大きい場合、本システムがプロセスのスタック領域の大きさを次のように仮定して確保します。仮想メモリの大きさとは、ulimit(1) コマンドの vmemory で表示される値です。S = M / 8S: プロセスのスタック領域の大きさ(byte)M: ラージページメモリと仮想メモリの小さい方の大きさ(byte)

スレッド毎のスタック領域は、プロセスのスタック領域と同じ大きさで確保されます。ただし、プロセスのスタック領域の制限値が、使用可能なラージページメモリと仮想メモリの大きさの小さい方をスレッド数で割った値より大きい場合、本システムがスレッド毎のスタック領域の大きさを次のように仮定して確保します。S = ( M / T ) / 5S: スレッド毎のスタック領域の大きさ(byte)M: ラージページメモリと仮想メモリの小さい方の大きさ(byte)T: スレッド数

スレッド毎のスタック領域の大きさを特定の大きさで確保したい場合には、環境変数THREAD_STACK_SIZE を使用してください。-Klargepage が指定された場合は、-Klargepage=1 が指定されたものと見なします。

例 :$ FCC -c fmain.cc$ FCC -c fsubs.cc$ FCC -Klargepage fmain.o fsubs.o

ラージページ機能がインストールされていないシステムで -Klargepage が指定された場合は、次のようなメッセージを出力し、エラーとなります。fjlpld: fatal: Large page resources not found. No output written to a.out

83

C++ 言語使用手引書

C.1.2 実行ラージページ機能を利用するプログラムは、Parallelnavi 環境下でのみ実行することができます。実行の方式は、ラージページ機能を利用しない従来のプログラムと変わりません。

例 :$ a.out

Parallelnavi 環境以外でラージページ機能を利用するプログラムを実行した場合は、次のようなメッセージを出力し、実行時エラーとなります。

例 1: 32 ビットモードで -Klargepage=1 を指定した場合$ a.out_32_lp1a.out_32_lp1: Cannot find /usr/lib/lpgld.so.1Killed

例 2: 32 ビットモードで -Klargepage=2 を指定した場合$ a.out_32_lp2a.out_32_lp2: Cannot find /usr/lib/lpgld2.so.1Killed

例 3: 64 ビットモードで -Klargepage=1 を指定した場合$ a.out_64_lp1a.out_64_lp1: Cannot find /usr/lib/sparcv9/lpgld.so.1Killed

例 4: 64 ビットモードで -Klargepage=2 を指定した場合$ a.out_64_lp2a.out_64_lp2: Cannot find /usr/lib/sparcv9/lpgld2.so.1Killed

翻訳時オプション -Klargepage=2 を指定した場合、実行開始時にスタック域が確保できないと、以下のエラーメッセージが出力されます。$ a.outlargepage run-time: stack segment allocation failed. Can't continue to run.

このメッセージが出力された場合、ヒープ域を拡大するか、またはスタック域の大きさを縮小してください。

C.1.3 ラージページ機能を利用するプログラムの判定ラージページ機能を利用するプログラムかどうかを判定するには、elfdump(1) コマンドを使います。elfdump(1) コマンドの出力に、lpgld という文字が含まれている場合は、ラージページ機能を利用するプログラムです。

例 1: 32 ビットモードで -Klargepage=1 を指定した場合$ elfdump -i a.out_32_lp1Interpreter Section: .interp /usr/lib/lpgld.so.1

例 2: 32 ビットモードで -Klargepage=2 を指定した場合$ elfdump -i a.out_32_lp2Interpreter Section: .interp /usr/lib/lpgld2.so.1

例 3: 64 ビットモードで -Klargepage=1 を指定した場合$ elfdump -i a.out_64_lp1Interpreter Section: .interp /usr/lib/sparcv9/lpgld.so.1

例 4: 64 ビットモードで -Klargepage=2 を指定した場合$ elfdump -i a.out_64_lp2Interpreter Section: .interp /usr/lib/sparcv9/lpgld2.so.1

C.1.4 制約事項ラージページ機能を利用するプログラムでは、以下の機能が制約されます。

スタティックリンクオプション

84

付録 C Parallelnavi

スタティックリンクオプション -dn は利用できません。

C.2 CPU 数の管理

Parallelnavi 環境では、プロセスが利用できる CPU 数が厳密に管理されます。下記の方法によって、CPU 数の上限値を指定することができますが、プログラム実行時のスレッド数の決定において、これらの設定が考慮されます。

NQS を利用する場合バッチキューの資源制限値(プロセスに割り当てるCPU数の設定:per_process_processor_limit)や、qsub の -lp オプションの指定が考慮されます。これを NQS のプロセスに割り当てる CPU 数と呼びます。なお、バッチリクエストの実行開始時には、環境変数 PARALLEL および OMP_NUM_THREADS に対して、NQS のプロセスに割り当てる CPU 数が設定されます。具体的には、自動並列化や OpenMP によって並列化されたプログラムのスレッド数は、次のように決定されます。なお、NQS の詳細は、「SystemWalker/ParallelWORKS 使用手引書 ネットワークキューイングシステム編」をお読みください。

C.2.1 自動並列化向けスレッド数の決定

CPU 数の上限値以下の値を CPU 数の上限値とします。

・ NQS のプロセスに割り当てる CPU 数

スレッド数並列に動作するスレッドの数は、まず以下の優先順位で決定されます。

1.環境変数 PARALLEL の指定値注

2.環境変数 OMP_NUM_THREADS の指定値3.NQS のプロセスに割り当てる CPU 数

上記の優先順位で決まったスレッド数と、CPU 数の上限値を比較して、小さい方を 終的なスレッド数として採用します。

C.2.2 OpenMP 向けスレッド数の決定

CPU 数の上限値以下の値を、CPU 数の上限値とします。

・ NQS のプロセスに割り当てる CPU 数

スレッド数並列実行のスレッド数は、高速実行時ライブラリを使用するとき OpenMP と自動並列化で共通となり、そうでないときそれぞれ独立に決定されます。高速実行時ライブラリの使用は、環境変数FLIB_FASTOMP の設定によって制御することができます。詳細は、「4.3 OpenMP 仕様による並列化」をお読みください。

高速実行時ライブラリを使用するとき(FLIB_FASTOMP が TRUE のとき)スレッド数は以下の優先順位で決定されます。

1.環境変数 OMP_NUM_THREADS の指定値注注

2.環境変数 PARALLEL の指定値

注 .結合編集時に -KOMP が指定され、かつ、環境変数 FLIB_FASTOMP に TRUE が設定されているとき、環境変数 OMP_NUM_THREADS の指定値があれば、その値と一致していなければなりません。一致していない場合には小さい方の値が採用されます。この時に、環境変数FLIB_C_MESSAGE が存在する場合には、mpc1042i-w のメッセージが出力されます。

注注 .結合編集時に -Kparallel が指定されているとき、環境変数 PARALLEL の指定値があれば、その値と一致していなければなりません。一致していない場合には小さい方の値が採用されます。この時に、環境変数 FLIB_C_MESSAGE が存在する場合には mpc1042i-w のメッセージが出力されます。

85

C++ 言語使用手引書

3.NQS のプロセスに割り当てる CPU 数この優先順位で決まるスレッド数が CPU 数の上限値を超えるとき、スレッド数は CPU 数の上限値となります。num_threads 節および omp_set_num_threads 関数によって指定する値は、ここで決まるスレッド数と一致していなければなりません。異なる値を指定した場合には、プログラムの実行が終了されます。この時に、環境変数 FLIB_C_MESSAGE が存在する場合には mpc1041i-s のメッセージが出力されます。

高速実行時ライブラリを使用しないとき(FLIB_FASTOMP が TRUE でないとき)OpenMP のスレッド数は、以下の優先順位で決定されます。自動並列化のスレッド数は、「C.2.1自動並列化向けスレッド数の決定」の記述に従います。1.parallel 指示子の num_threads 節の指定値2.omp_set_num_threads 関数の指定値3.環境変数 OMP_NUM_THREADS の指定値4.環境変数 PARALLEL の指定値5.NQS のプロセスに割り当てる CPU 数

動的スレッド調整機構が有効な場合には、この優先順位で決まるスレッド数が CPU 数の上限値を超えるとき、スレッド数は CPU 数の上限値になります。動的スレッド調整機構が無効な場合、1CPU 当たりのスレッド数が 1 を超える場合には、並列に実行されることを意図したスレッドが時分割で実行されることになります。このような場合、スレッド間の同期処理のオーバヘッドが大きくなり、実行性能が低下することがあります。システムによる負荷も考慮して、1CPU 当たりのスレッド数が 1 以下になるようにスレッド数を設定することをお勧めします。

C.3 スレッド間ハードウェアバリア機能

Parallelnavi 環境では、ハードウェアバリア機構が実装されている場合、スレッド間ハードウェアバリア機能を利用することができます。スレッド間ハードウェアバリア機能とは、スレッド並列処理における同期処理を高速にし、実行性能を向上させる機能です。スレッド間ハードウェアバリア機能の詳細は、「Parallelnavi 使用手引書」をお読みください。

C.3.1 翻訳スレッド間ハードウェアバリア機能を利用するプログラムを作成するためには、-Khardbarrierを結合編集時に指定する必要があります。オブジェクトファイルだけを作成する場合には、-Khardbarrier を指定する必要はありません。なお、何も指定されない場合や、-Khardbarrier が指定されていても -Kparallel または -KOMPが同時に指定されていない場合には、スレッド間ハードウェアバリア機能に対応したプログラムは作成されません。

例 :-Khardbarrier の指定$ FCC -Kparallel -c fmain.cc$ FCC -Kparallel -c fsubs.cc$ FCC -Kparallel -Khardbarrier fmain.o fsubs.o

Parallelnavi がインストールされていないシステムで、-Khardbarrier が指定された場合は、次のようなメッセージを出力し、エラーとなります。ld: fatal: library -lpnbar: not found

C.3.2 実行スレッド間ハードウェアバリア機能を利用するプログラムは、Parallelnavi 2.0 以上の環境下でのみ実行することができます。実行の方式は、スレッド間ハードウェアバリア機能を利用しない従来のプログラムと変わりません。ただし、スレッド間ハードウェアバリア機能を活用するためには、NQS の Node 内バリア資源が割り当てられている必要があります。

例 : スレッド間ハードウェアバリア機能を利用するプログラムの実行$ cat script#!/bin/sh./a.out$ qsub -qmulti -lb1 script

86

付録 C Parallelnavi

Parallelnavi の NQS 環境以外でスレッド間ハードウェアバリア機能を利用するプログラムを実行した場合や、NQS のハードウェアバリア資源が割り当てられなかった場合には、自動的に同期処理をソフトウェアバリア方式に切り替え、実行を続けます。-KOMP を指定して翻訳したプログラムでスレッド間ハードウェアバリアを利用する場合には、環境変数 FLIB_FASTOMP が TRUE に設定されていなければなりません。環境変数 FLIB_FASTOMP の意味と使用上の注意については、「4.3 OpenMP 仕様による並列化」をお読みください。環境変数 FLIB_HARDBARRIER_MESSAGE および FLIB_C_MESSAGE が存在した場合、-Khardbarrierを指定したものの、何らかの理由によりスレッド間ハードウェアバリア機能が利用できない場合には、以下のメッセージが出力されます。mpc1043i-i "A thread hardware barrier couldn't be used."

環境変数 FLIB_NOHARDBARRIER が存在した場合、翻訳時オプションに関わらず、スレッド間ハードウェアバリア機能を使用しません。

C.3.3 スレッド間ハードウェアバリア機能を利用するプログラムの判定スレッド間ハードウェアバリア機能を利用するプログラムなのかどうかを判定するには、ldd(1)コマンドを使います。ldd(1) コマンドの出力に、libpnbar.so という文字が含まれている場合は、スレッド間ハードウェアバリア機能を利用するプログラムです。

C.3.4 制約事項スレッド間ハードウェアバリア機能を利用するプログラムでは、以下の機能が制約されます。

fork(2) 時の子プロセスでの利用スレッド間ハードウェアバリア機能を利用しているプログラムが fork システムコールを発行した場合、生成されたプロセスにおいてはスレッド間ハードウェアバリア機能を利用することができません。

87

C++ 言語使用手引書

88