インテル® C++ コンパイラー 19.0 デベロッパー・ガイドおよびリファレンス
整数および浮動小数点 (float、double、または long double) データを同一の計算に混在させないようにします。浮動小数点算術式 (代入文) のすべての数を浮動小数点値として表現することで、固定形式と浮動小数点形式間のデータ変換が不要となります。また、整数算術式のすべての数を整数値として表現することにも、同様の利点があります。これによってランタイム・パフォーマンスは向上します。
例えば、I と J がともに 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 |