このドキュメントでは、次のトピックについて説明します。
算術演算でパック型数値(P)および整数(I4)のデータフォーマットを使用する場合に、最適なパフォーマンスが得られます。
パック型数値(P)、アンパック型数値(N)、整数(I)、および浮動小数点(F)のフォーマット間のデータ変換は避けます。最適化されたコードであっても、処理オーバーヘッドが発生するためです。
最適化されたコードでは、解釈のオーバーヘッドがないため、さまざまなデータフォーマット間の相違はより顕著になります。例えば、最適化されたコードの場合にフォーマット N ではなく P を使用することで得られるパフォーマンスの向上は、通常のコードの場合よりも大きくなります。
A = A + 1
上記の数値計算の場合
最適化されていないコードでは、フォーマット P での実行はフォーマット N よりも約 13 %速くなります。
ただし、最適化されたコードでは、フォーマット P での実行はフォーマット N よりも約 56 %速くなります。
この単純なステートメントに Natural Optimizer Compiler を適用することで得られるパフォーマンスの向上は、以下のとおりです。
アンパック型オペランド(N)の場合:8 倍高速
パック型オペランド(P)の場合:15 倍高速
以下のような配列範囲処理は、
MOVE A(*) TO B(*)
同じ機能を FOR
ステートメント処理ループを使用してプログラムした場合よりも、効率的に実行されます。 このことは、最適化されたコードにも該当します。
索引を使用する場合、最適なパフォーマンスを得るには整数フォーマット I4 を使用する必要があります。
英数字定数を英数字変数(フォーマット A)に移動する場合、または英数字変数を英数字定数と比較する場合、英数字定数の長さを変数の長さに合わせて調整することをお勧めします。 これによって、処理は大幅に速くなります。例えば、以下のようにすると
A(A5):='XYZAB' ... IF A = 'ABC ' THEN ...
以下の場合よりも速くなります。
IF A = 'ABC' THEN ...
DECIDE ON
ステートメントをシステム変数、配列、またはパラメータ operand1
とともに使用する場合、LOCAL
ストレージセクションで定義されている同じタイプおよび長さのスカラ変数に値を移動したほうが効率的です。
割り当てまたは算術演算で数値定数を使用する場合は、定数が処理と同じタイプになるようにしてください。
小数の有無は任意だが指数のない数値定数は、値を表現する最小の長さと精度を持つパック型数値にコンパイルされます。ただし、定数が配列の添字またはサブストリングの開始位置または長さの場合は、4 バイトの整数(I4)になります。 このルールは、演算に参加する変数のタイプに関係なく適用されます。
浮動小数点を含む演算は、浮動小数点で実行されます。 E00
を数値に追加して、強制的に浮動小数点にします。以下に例を示します。
ADD 1E00 to F(F8)
浮動小数点は含まないが、パック型数値、アンパック型数値、日付または時刻変数を含む演算は、パック 10 進で実行されます。 ADD
、SUBTRACT
、および IF
の場合、小数位と末尾のゼロを追加して、数値定数が一番精度の高い変数と同じ数の小数位を持つようにします。以下に例を示します。
ADD 1.00 TO P(P7.2)
この方法は MULTIPLY
および DIVIDE
には必要ありません。
最適化処理を簡単にするには、すべてのスカラ参照をデータセクションの最初に、すべての配列参照をデータセクションの最後に置くようにします。
Natural Optimizer Compiler には、パフォーマンスをさらに高めるアルゴリズムが含まれています。 パフォーマンスの観点では、ステートメントはオペランドのタイプによって異なります。 1 つ以上のオペランドがパラメータ、配列、またはタイプ N(数値)のスカラフィールド、あるいはこれらのオペランドの組み合わせである場合、ステートメントの実行は遅くなります。 NOC では、プログラムフローが分析され、これらの特性の 1 つ以上を持つどの変数が、書き込みなしで複数回読み込まれるかが判別されます。 次に、各変数の値は、以下の条件に従って、一時キャッシュエリアに移動されてすばやくアクセスされます。
変数は、複数回アクセスされるが、ほとんど変更されない。かつ
変数は、任意のタイプの配列またはタイプ N(数値)のスカラフィールドである。
変数のキャッシュに最も適しているのは、同じ変数に繰り返しアクセスする長いシーケンスを含むプログラムであり、特に変数が配列である場合です。 変数のキャッシュによって、複雑で何度も繰り返されるアドレス計算が回避されます。
以下のサンプルプログラムは、変数のキャッシュの利点を示しています。 NODBG
(下記参照)および CACHE=ON
でカタログして、このプログラムをテスト環境で実行すると、NODBG
および CACHE=OFF
でプログラムを実行する場合に必要となる時間の 47 %かかりました。 プログラムを CACHE=ON
でカタログすると、NOC によって生成されるコードは 856 バイトから 376 バイトに削減されます。
DEFINE DATA LOCAL 1 ARR(N2/10,10,10) 1 I(I4) INIT <5> 1 J(I4) INIT <6> 1 K(I4) INIT <7> END-DEFINE DECIDE ON EVERY ARR(I,J,K) VALUE 10 IGNORE VALUE 20 IGNORE VALUE 30 IGNORE VALUE 40 IGNORE VALUE 50 IGNORE VALUE 60 IGNORE VALUE 70 IGNORE VALUE 80 IGNORE VALUE 90 IGNORE NONE IGNORE END-DECIDE
注意: キャッシュされている変数の内容を Natural デバッガのコマンド MODIFY VARIABLE で変更すると、元の変数の内容のみが変更されます。 キャッシュされている値(後続のステートメントで使用される可能性がある)は変更されません。 そのため、Natural デバッガを使用する場合は、変数のキャッシュの使用に注意する必要があります。
Natural の『デバッガ』ドキュメントも参照してください。 |
プログラムを完全にテストして実稼働に移したら、「Optimizer オプション」セクションで説明されているように、プログラムを NODBG オプションでカタログする必要があります。 デバッグコードがないと、最適化されたステートメントの実行は 10 %~30 %速くなります。
このオプションを指定すると、INDX
または OVFLW
オプションがオンになっていても、デバッグを容易にするためのコードは削除されます。