インテル® C++ コンパイラー 19.0 デベロッパー・ガイドおよびリファレンス
コンテナーの範囲、コンテナー内の位置、またはコンテナーの境界を指定する場合、次の 3 つの形式で整数値を指定できます: fixed、aligned、および int。fixed が最も厳密で int が最もあいまいです。できるだけ厳密な形式を指定してください。情報が多いほうが、コンパイラーは効率良く最適化を行うことができます。
コンパイル時に値が指定される数値定数を表します。
template <int NumberT> class fixed;
SIMD ループ内でインデックス値に適用されるオフセットがコンパイル時に分かっている場合、コンパイラーはその情報を利用できます。例えば、境界が固定で、データレイアウトへのアクセスがアライメントされていることが分かっている場合、アライメントされたアクセスを維持します。隣接する位置への複数のアクセスがある場合、コンパイラーは同じキャッシュラインへのアクセスを検出し、そのキャッシュラインを繰り返しプリフェッチしないようにできます。また、コンパイル時に反復空間の開始位置が分かっており、それが SIMD レーン数の倍数の場合、コンパイラーはピールループの生成をスキップできます。可能な限り、aligned や int ではなく fixed を使用すべきです。
std::integral_constant<int> も同様の機能を提供しますが、多重定義演算子を提供し、ほかのコードの std::integral_constant<int> と競合しないように、ライブラリーは独自の型を定義しています。
次の表は、fixed のテンプレート引数の情報です。
テンプレート引数 | 説明 |
---|---|
int Number T |
fixed が表す数値。 |
次の表は、fixed のメンバーの情報です。
メンバー | 説明 |
---|---|
static constexpr int value = NumberT |
コンパイル時に分かっている数値。 |
constexpr operator value_type() const |
戻り値: 数値。 |
constexpr value_type operator()() const; |
戻り値: 数値。 |
コンパイル時に評価される、型 sdlt::fixed<> で定義されている定数式の算術演算子 +、- (単項および 2 項)、*、/。
サフィックス _fixed は、C++11 のユーザー定義の同等のリテラルです。例えば、1080_fixed は fixed<1080> と同等です。次の 2 つのサンプルコードの可読性について考えてみます。
foo3d(fixed<1080>(), fixed<1920>());
と
foo3d(1080_fixed, 1920_fixed);
コンパイル時に IndexAlignment の倍数となることが分かっている整数値を表します。
template <int IndexAlignmentT> class aligned;
整数が既知の値の倍数であることをコンパイラーに知らせると、コンパイラーは SIMD ループ内のインデックスとその情報を組み合わせて、データレイアウトにアクセスする際にアライメントされたアクセスを維持します。
内部で、整数値はブロックカウントに変換されます。
block_count = value/IndexAlignmentT;
多重定義の数学演算は、必要に応じて、アライメントされたブロックカウントを使用できます。value() は AlignmentT*block_count で表され、コンパイラーは value() が AlignmentT の倍数であることを簡単に証明できるため、アライメントによる最適化を利用できます。
次の表は、aligned のテンプレート引数の情報です。
テンプレート引数 | 説明 |
---|---|
int IndexAlignmentT |
ユーザーによって指定されるアライメント境界。整数値はこの値の倍数になります。IndexAlignmentT は 2 の累乗でなければなりません。 |
次の表は、aligned のメンバーとして定義されている型の情報です。
メンバーの型 | 説明 |
---|---|
typedef int value_type |
数値の型。 |
typedef int block_type |
block_count の型。 |
次の表は、aligned のメンバーの情報です。
メンバー | 説明 |
---|---|
static const int index_alignment |
IndexAlignmentT 値。 |
aligned() |
空の (初期化されていない) オブジェクトを構築します。 |
explicit aligned(value_type) |
block_count=a_value/IndexAlignmentT の計算を構築します。 |
aligned(const aligned& a_other) |
a_other から block_count のコピーを構築します。a_other の IndexAlignmentT は同じでなければなりません。 |
template<int OtherAlignment> explicit aligned(const aligned& other) |
other.value() の計算を排除して最適化された block_count の計算を構築します。IndexAlignmentT は a_other < IndexAlignmentT で、other.value() は IndexAlignmentT の倍数でなければなりません。 |
template<int OtherAlignment> aligned(const aligned& other) |
除算ではなく乗算を使用して block_count の計算を構築します。IndexAlignmentT は、a_other > IndexAlignmentT でなければなりません。 |
static aligned from_block_count(block_type block_count) |
提供される block_count を操作せずに直接使用して aligned のインスタンスを作成します。 |
value_type value() const |
aligned で表された値を計算します。 戻り値: aligned_block_count()*IndexAlignmentT。 |
operator value_type() |
int に変換します。 戻り値: value()。 |
block_type aligned_block_count() const |
int に変換します。 戻り値: ブロックカウント。 |
演算 | 説明 |
---|---|
operator *(int), commutative |
スケール値。 戻り値: aligned<IndexAlignmentT>。 |
operator *(fixed<V>), commutative |
IndexAlignment を 2^M で、値を K でスケーリングします。V=2^M*K (V は 2 の累乗の倍数) でなければなりません。 戻り値: aligned<IndexAlignmentT*(2^M)>。 |
operator *(aligned<OtherAl>) |
IndexAlignment を OtherAl で、block_count を引数でスケーリングします。 戻り値: aligned<IndexAlignmentT*OtherAl>。 |
int operator/(fixed<IndexAlignmentT>) |
戻り値: aligned_block_count()。 |
int operator/(fixed<-IndexAlignmentT>) |
戻り値: -aligned_block_count();。 |
int operator/(fixed<V>) |
abs(V)>IndexAlignmentT && IndexAlignmentT%V==0 でなければなりません。 戻り値: aligned_block_count()/(V/IndexAlignmentT)。 |
int operator/(fixed<V>) |
abs(V) < IndexAlignmentT && V%IndexAlignmentT==0 でなければなりません。 戻り値: aligned_block_count()*(IndexAlignmentT/V)。 |
aligned operator -() |
戻り値: 同じ aligned 型の符号反転値。 |
aligned operator -(const aligned &) const |
戻り値: 同じ aligned 型の差分値。 |
template<int OtherAl> aligned<?> operator -(const aligned<OtherAl>&) const |
ほかのアライメントとの差分値。動作と戻り値のアライメントは、オペランドのアライメントの関係に依存します。 戻り値: 渡されたアライメントのうち低いほうで表された差分値。 |
template<int V> aligned<?> operator -(const fixed<V> &) const |
固定値との差分。動作と戻り値のアライメントは、aligned<> オペランドと V の値の関係に依存します。 戻り値: 調整されたアライメントで表された差分値。 |
aligned operator +(const aligned &)const |
戻り値: 同じ aligned の合計。 |
template<int OtherAl> aligned<?> operator +(const aligned<OtherAl>&) const |
ほかのアライメントとの合計。動作と戻り値のアライメントは、オペランドのアライメントの関係に依存します。 戻り値: 渡されたアライメントのうち低いほうで表された合計値。 |
template<int V> aligned<?> operator +(const fixed<V> &) const |
固定値との合計。動作と戻り値のアライメントは、aligned<> オペランドと V の値の関係に依存します。 戻り値: 調整されたアライメントで表された合計値。 |
template<int OtherAl> aligned operator +=(const aligned<OtherAl> &) const |
IndexAlignmentT が OtherAl と互換性がある場合は、アライメントされたオブジェクトの値をインクリメントします。 戻り値: 同じ aligned 型のインクリメントされた値。 |
template<int OtherAl> aligned operator -=(const aligned<OtherAl> &) const |
IndexAlignmentT が OtherAl と互換性がある場合は、アライメントされたオブジェクトの値をデクリメントします。 戻り値: 同じ aligned 型のデクリメントされた値。 |
template<int OtherAl> aligned operator *=(const aligned<OtherAl> &) const |
IndexAlignmentT が OtherAl と互換性がある場合は、アライメントされたオブジェクトの値を乗算します。 戻り値: 同じ aligned 型の積。 |
template<int OtherAl> aligned operator /=(const aligned<OtherAl> &) const |
IndexAlignmentT が OtherAl と互換性がある場合は、アライメントされたオブジェクトの値を除算します。 戻り値: 同じ aligned 型の商。 |
任意の整数値を表します。fixed<> 値と aligned<> 値がサポートされるインターフェイスでは、整数値も使用することができます。3 つの形式のうち最も情報が少ないため、コンパイラーによる最適化も最小になります。