仮別名化の仮定

Visual Fortran (または Compaq Fortran と Compaq Fortran 77) でコンパイルされた一部のプログラムは,他の Fortran コンパイラとは異なる結果を出すことがあります。これは,仮引数を互いに,または共通ブロックまたは結合を通して共有された変数を別名化しており,少なくとも 1 つの変数が格納されているようなプログラムで起こります。

このようなプログラムの動作は,Fortran 90 標準に準拠しているプログラムでは禁止されていますが,Visual Fortran では禁止されていません。他のバージョンの Fortran は,仮別名を許容し,正しい結果が得られることを確認します。しかし,Visual Fortran は仮別名化が行われないものと仮定し,実行を高速化するために,これを原因とするデータ依存関係の可能性を無視することがあります。

Visual Fortran の基本設定は,Fortran 90 標準に準拠しているプログラムにとっては安全です。標準では,プログラム単位の実行中に重複した変数または配列への代入が行われる場合,これらの変数または配列を実引数として受け渡すことが禁止されているので,この標準に準拠しているプログラムでは性能が向上します。

/assume:dummy_aliases オプションは仮別名化を許可します。このオプションは,仮変数と共通変数の引用が正しい順序で行われているものと仮定することで,正しい結果が得られることを保証します。この動作を利用しているプログラム単位は,/assume:nodummy_aliases を使ってコンパイルすると,不正確な結果を出す可能性があります。

次の例は,FORTRAN 77 バージョンの基本線形代数サブルーチン (BLAS) から取った DAXPY ルーチンです。この例は /assume:dummy_aliases オプションの使い方を示しています。

	SUBROUTINE DAXPY(N,DA,DX,INCX,DY,INCY)
C	Constant times a vector plus a vector.
C	uses unrolled loops for increments equal to 1.
	DOUBLE PRECISION DX(1), DY(1), DA
	INTEGER I,INCX,INCY,IX,IY,M,MP1,N
C
	IF (N.LE.0) RETURN
	IF (DA.EQ.0.0) RETURN
	IF (INCX.EQ.1.AND.INCY.EQ.1) GOTO 20
C	Code for unequal increments or equal increments
C	not equal to 1.
	.
	.
	.
	RETURN
C	Code for both increments equal to 1.
C	Clean-up loop
  20	M = MOD(N,4)
	IF (M.EQ.0) GOTO 40
	DO I=1,M
	   DY(I) = DY(I) + DA*DX(I)
	END DO
	IF (N.LT.4) RETURN
  40	MP1 = M + 1
	DO I = MP1, N, 4
	   DY(I) = DY(I) + DA*DX(I)
	   DY(I + 1) = DY(I + 1) + DA*DX(I + 1)
	   DY(I + 2) = DY(I + 2) + DA*DX(I + 2)
	   DY(I + 3) = DY(I + 3) + DA*DX(I + 3)
	END DO
	RETURN
	END SUBROUTINE

第 2 の DO ループは DY への代入を含んでいます。DYDA と重複していると,DY に対する代入は DA に新しい値を与える可能性があり,この重複が結果に影響を与えることになります。この重複が必要な場合,引用のたびに DA をメモリーから取り出さなくてはなりません。DA を繰り返し取り出すことで,性能が低下します。

反対の設定を持つルーチンのリンク

/assume:dummy_aliases オプションでコンパイルされたルーチンを,/assume:nodummy_aliases でコンパイルされたルーチンとリンクすることができます。たとえば,仮別名付きで呼び出されるルーチンが 1 つしかない場合,そのルーチンをコンパイルするときに /assume:dummy_aliases を使用し,他のすべてのルーチンを /assume:nodummy_aliases でコンパイルして,このオプションの性能上の有利さを利用することができます。

DADY と重複する状況で DAXPY を呼び出すプログラムは,FORTRAN 77 および Fortran 90 標準に準拠していません。しかし,コンパイルの際に /assume:dummy_aliases を使用すれば,そのような DAXPY ルーチンも許容されます。