インテル® C/C++ および Fortran コンパイラーのバージョン 16.0 以降では、プログラマーがスカラー関数に対応するベクトル関数を明示的に記述することを可能にする、ベクトル異形関数 (Vector Variant Function) をサポートしています。
Windows* および Linux* 環境で以下の構文で記述できます:
Windows*
__declspec(vector_variant(節))
Linux*:
__attribute__((vector_variant(節)))
ここで、節の 1 つにターゲットの命令アーキテクチャー・セットを指定する processor() 節がサポートされています。コンパイラーのマニュアルには、Core_4th_gen_avx_tsx までしか CPUID 値が記述されていませんが、Broadwell✝ 以降のプロセッサーを対象とするには次の値を指定します。
追加された CPUID の値
Future_cpu_21 // Broadwell✝ no TSX
Future_cpu_21_tsx // Broadwell✝ TSX
Future_cpu_22 // KNL✝
Future_cpu_23 // Skylake✝
これ以外の値については、こちらをご覧ください。
この値は、ベクトル異形関数だけでなく、手動でターゲット・プロセッサーの実行コードを記述する__declspec(cpu_dispatch(cpuid, cpuid,…)) 構文にも適用できます。
以下に、ベクトル異形関数の記述例を示します。
#include<immintrin.h> __declspec(noinline) float MyAdd(float* a, int b) { return *a + b; } __declspec(vector_variant(implements(MyAdd(float *a, int b)), linear(a), vectorlength(8), nomask, processor(future_cpu_16))) __m256 MyAddVec(float* v_a, __m128i v_b, __m128i v_b2) { __m256i t96 = _mm256_castsi128_si256(v_b); __m256i tmp = _mm256_insertf128_si256(t96, v_b2, 1); __m256 t95 = _mm256_cvtepi32_ps(tmp); return _mm256_add_ps(*((__m256*)v_a), t95); } float x[2000], y[2000]; float foo(float y[]) { #pragma omp simd for (int k=0; k<2000; k++) { x[k] = MyAdd(&y[k], k); } return x[0] + x[1999]; }
✝開発コード名
コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください