プログラムが正常にコンパイルおよびリンクしても、実行時に予期しない結果を起こす場合があります。 コンパイラーは、言語の構文規則に違反しないプログラミング・エラーは診断しません。 このセクションでは、一般的なエラーとその発見方法、および訂正方法を説明しています。
初期化されていない変数
自動ストレージ期間を持つオブジェクトは、暗黙的に初期化されないため、初期値は未定です。 auto 変数が値を設定される前に使用されると、 プログラムの実行のたび、同じ結果を生成するかどうかが一定していません。 コンパイラー・オプション -qinfo=gen を指定すると、 値が設定される前に使用されている auto 変数の位置を表示します。 -qinitauto オプションは、すべての自動変数を指定した値で初期化するように コンパイラーに指示します。 このオプションを使用すると、アプリケーションの実行時のパフォーマンスが落ちるため、 デバッグ時にのみ使用することをお勧めします。
実行時検査
-qcheck オプションを指定すると、 実行可能ファイルに実行時検査のコードを挿入します。 サブオプションで、NULL ポインター、配列の範囲を超える指標付け、 およびゼロによる除法を検査するように指定します。 -qinitauto と同様に、-qcheck も アプリケーションのパフォーマンスが低下するため、デバッグ目的でのみ使用することが推奨されます。
ANSI 別名割り当て
型ベースの別名割り当て (「ANSI 別名割り当て」とも呼ばれます) では、 データ・オブジェクトに安全にアクセスするために使用できる左辺値を制限します。 言語標準への準拠を強制する言語レベルでコンパイルすると、C および C++ コンパイラーは、最適化を行うときに型ベースの別名割り当てを必ず実行します。 ANSI の別名割り当て規則では、ポインターは、 同じ型のオブジェクトか、互換性のある型のオブジェクトに対してのみ 間接参照することができると規定されています。 この規則の例外は、符号および型の修飾子には型ベースの別名割り当ては適応されないこと、 および文字型ポインターはどのタイプも指し示すことができるということです。 よく使用されるコーディング方法として、ポインターを非互換の型にキャストしてから 間接参照することがありますが、これはこの規則に違反しています。
-qalias=noansi を設定して、ANSI 別名割り当てをオフにすると、 プログラムの動作は訂正できるかもしれませんが、コンパイラーがアプリケーションを最適化できる機会を減らし、 実行時のパフォーマンスが劣化します。 推奨される解決策は、プログラムを修正して型ベースの別名割り当て規則に合わせることです。
#pragma option_override
最適化を使用している場合にのみエラーが表示される場合があります。 複雑なアプリケーションでは、プログラミング・エラーを含むことが分かっている関数に対して最適化をオフにし、 プログラムの残りの箇所では最適化をオンにすると、特に有益な場合があります。 #pragma option_override ディレクティブを使用して、 特定の関数に別の最適化オプションを指定することができます。
#pragma option_override ディレクティブは、 エラーの原因となっている関数を判別するために使用することもできます。 問題の関数を見つけるには、エラーが出なくなるまで、 ディレクティブ内でそれぞれの関数の最適化を順番にオフにしていきます。
プログラムの並列実行を実現し、シングル・プロセッサーで実行するよ り高速でジョブを完了するための、証明された手法がいくつかあります。 これらの手法には、以下のものがあります。
アプリケーションの移植性要件は、明らかに、使用に最適な技法を選択する際の要因です。 この選択はまた、アプリケーション、プログラマーのスキルおよび設定、およびターゲット・マシンの特性に非常に依存します。 AIX での並列処理を達成する 2 つの主要な方法は、手動でコーディングした POSIX スレッド (pthread) の使用と OpenMP ディレクティブの使用です。
AIX オペレーティング・システムの並列プログラミング機能はスレッドの概念に基づいています。 並列プログラミングはマルチプロセッサー・システムの利点を活用しなが ら、既存の単一プロセッサー・システムで完全なバイナリー互換性を維持しています。 これは、単一プロセッサー・システムで作業するマルチスレッドのプログラムは、再コンパイルなしでマルチプロセッサー・システムを利用することができることを意味します。
pthread は、並列処理プロセスの最大限の制御を提供するため、複数 のプロセッサーを効率的に使用する優れた柔軟性が実現します。 そのトレードオフとして、コードが大幅に複雑化します。多くの場合、OpenMP ディレクティブ、 SMP 対応ライブラリー、またはコンパイラーの自動 SMP 機能の使用と いった簡単な方法が推奨されます。スレッドを明示的に使用しても、 必ずしもパフォーマンスが向上するわけではありません。マルチスレッドのアプリケーションをデバッグすると、 どうしても問題が起こりがちです。ただし、一部のプログラムでは、これのみが実行可能な方法です。
以下に各技法の利点と欠点の一部をリストします。
コンパイラーによる自動並列処理
SMP 対応ライブラリー
OpenMP ディレクティブ
ハイブリッド・アプローチ (OpenMP および pthread のサブセットまたは混合、または UNIX fork() および exec() 並列処理、プラットフォーム固有の構文)
pthread
OpenMP ディレクティブは、特定のループをどのように並列処理するかをコンパイラーに命令するコマンド・セットです。 ソースにディレクティブがあると、コンパイラーが並列コードで並列分析を実行する必要がなくなります。 OpenMP ディレクティブを使用するには、並列処理に必要なインフラストラクチャーを提供する pthread ライブラリーが必要です。
OpenMP ディレクティブは、アプリケーションの並列処理に重要な 3 つの問題に取り組みます。 まず、文節およびディレクティブはスコープ変数に使用可能です。 ほとんどの場合、変数を共有するべきではありません。つまり、プロセッサーはそれぞれ、それ自身の変数のコピーを持っている必要があります。 第 2 に、作業共用ディレクティブは、コードの並列領域に含まれる作業を 複数の SMP プロセッサー間で分散させる方法を指定します。 最後に、プロセッサー間で同期用のディレクティブがあります。
コンパイラーは OpenMP バージョン 2.0 仕様をサポートします。
関連参照