インテル® C++ コンパイラー 18.0 デベロッパー・ガイドおよびリファレンス

混在データ型算術式の回避

整数および浮動小数点 (float、double、または long double) データを同一の計算に混在させないようにします。浮動小数点算術式 (代入文) のすべての数を浮動小数点値として表現することで、固定形式と浮動小数点形式間のデータ変換が不要となります。また、整数算術式のすべての数を整数値として表現することにも、同様の利点があります。これによってランタイム・パフォーマンスは向上します。

例えば、IJ がともに int 変数である場合、定数 (2.) を整数値 (2) として表現することで、データを変換する必要がなくなります。次の例では、非効率的なコードと効率的なコードをそれぞれ紹介します。

非効率的なコードの例

int I, J;
  I = J / 2.
;

効率的なコードの例

int I, J;
  I = J / 2;

最内ループの自動ベクトル化に関する注意事項

最内ループの自動ベクトル化では、連続したループ反復からの複数のデータ要素を、128 ビット (インテル® SSE) または 256 ビット (インテル® AVX) のサイズで 1 つのベクトルレジスターにパックします。

例えば、REAL と DOUBLE PRECISION の異なるサイズのデータを使用するループについて考えてみます。REAL データでは、コンパイラーは 4 つ (インテル® SSE) または 8 つの (インテル® AVX) の連続した反復からデータ要素をパックします (32 ビット x 4 = 128 ビット、32 ビット x 8 = 256 ビット)。DOUBLE PRECISION データでは、2 つ (インテル® SSE) または 4 つの (インテル® AVX) の連続した反復からデータ要素をパックします (64 ビット x 2 = 128 ビット、64 ビット x 4 = 256 ビット)。この場合、反復数が一致しないため、ループの自動ベクトル化に失敗することがあります。

最内ループの自動ベクトル化に失敗した場合、同じサイズのデータを使用することを推奨します。INTEGER と REAL はどちらも 32 ビットなので、同じサイズのデータとして考えられます。

例 1: 自動ベクトル化が不可のコード

DOUBLE PRECISION A(N), B(N) 
REAL C(N), D(N) 
DO I=1, N
   A(I)=D(I)
   C(I)=B(I) 
ENDDO

例 2: 2 つのループへの自動分配後に自動ベクトル化が可能なコード

DOUBLE PRECISION A(N), B(N) 
REAL C(N), D(N) 
DO I=1, N
   A(I)=B(I)
   C(I)=D(I) 
ENDDO

例 3: 1 つのループとして自動ベクトル化が可能なコード

REAL A(N), B(N) 
REAL C(N), D(N) 
DO I=1, N
   A(I)=B(I)
   C(I)=D(I) 
ENDDO