SIMDライブラリ
SIMDライブラリは、データ並列性を明示的に記述し、より効率的なSIMDアクセスのためにデータを構造化するためのポータブルな型を提供します。
型 simd<T> のオブジェクトは、型 T のオブジェクトと同様に振る舞います。しかし、T が1つの値を格納し操作するのに対し、simd<T> は複数の値を格納し操作します(これは幅 (width) と呼ばれますが、標準ライブラリの他の部分との一貫性のために size と識別されます。 simd_size を参照してください)。
simd<T> に対するすべての演算子と操作は、要素ごと (element-wise) に作用します(ただし、水平 (horizontal) 操作は明確にそのようにマークされており、例外です)。この単純なルールはデータ並列性を表現し、コンパイラがSIMD命令や独立した実行ストリームを生成するために使用されます。
型 simd<T> と native_simd<T> の幅は、コンパイル時に実装によって決定されます。対照的に、型 fixed_size_simd<T, N> の幅は、開発者によって特定のサイズに固定されます。
異なるSIMD型を高い効率で混合して使用するための推奨パターンは、native_simd と rebind_simd を使用します。
#include <experimental/simd> namespace stdx = std::experimental; using floatv = stdx::native_simd<float>; using doublev = stdx::rebind_simd_t<double, floatv>; using intv = stdx::rebind_simd_t<int, floatv>;
これにより、型のセットがすべて同じ幅を持つことが保証され、したがって相互に変換可能になります。幅が一致しない変換は、値をドロップするか、値をでっち上げる必要があるため、定義されていません。サイズ変更操作のために、SIMDライブラリは split と concat 関数を提供します。
| ヘッダー
<experimental/simd> で定義 |
目次 |
[編集] 主要なクラス
| (parallelism TS v2) |
データ並列ベクトル型 (class template) |
| (parallelism TS v2) |
要素型がboolのデータ並列型 (class template) |
[編集] ABIタグ
| 名前空間
std::experimental::simd_abi で定義 | |
| (parallelism TS v2) |
単一の要素を格納するためのタグ型 (typedef) |
| (parallelism TS v2) |
指定された数の要素を格納するためのタグ型 (エイリアステンプレート) |
| (parallelism TS v2) |
ABI互換性を保証するタグ型 (エイリアステンプレート) |
| (parallelism TS v2) |
最も効率的なタグ型 (エイリアステンプレート) |
| (parallelism TS v2) |
fixedでサポートが保証されている要素の最大数 (定数) |
| (parallelism TS v2) |
与えられた要素型と要素数に対するABI型を取得する (クラステンプレート) |
[編集] アライメントタグ
| (parallelism TS v2) |
ロード/ストアアドレスが要素のアライメントに揃っていることを示すフラグ (クラス) |
| (parallelism TS v2) |
ロード/ストアアドレスがベクトルのアライメントに揃っていることを示すフラグ (クラス) |
| (parallelism TS v2) |
ロード/ストアアドレスが指定されたアライメントに揃っていることを示すフラグ (クラステンプレート) |
[編集] Where式
| (parallelism TS v2) |
非変更操作で選択された要素 (クラステンプレート) |
| (parallelism TS v2) |
変更操作で選択された要素 (クラステンプレート) |
| (parallelism TS v2) |
const_where_expression と where_expression を生成する (関数テンプレート) |
[編集] キャスト
| (parallelism TS v2) |
要素ごとの static_cast (関数テンプレート) |
| (parallelism TS v2) |
要素ごとの ABI キャスト (関数テンプレート) |
| (parallelism TS v2) |
単一のsimdオブジェクトを複数のオブジェクトに分割する (関数テンプレート) |
| (parallelism TS v2) |
複数のsimdオブジェクトを単一のオブジェクトに連結する (関数テンプレート) |
[編集] アルゴリズム
| (parallelism TS v2) |
要素ごとの最小値操作 (関数テンプレート) |
| (parallelism TS v2) |
要素ごとの最大値操作 (関数テンプレート) |
| (parallelism TS v2) |
要素ごとの最小・最大値操作 (関数テンプレート) |
| (parallelism TS v2) |
要素ごとの clamp 操作 (関数テンプレート) |
[編集] リダクション
| (parallelism TS v2) |
ベクトルを単一の要素に縮約する (関数テンプレート) |
[編集] マスクリダクション
| (parallelism TS v2) |
simd_mask から bool へのリダクション (関数テンプレート) |
| (parallelism TS v2) |
simd_mask を true の値の数にリダクションする (関数テンプレート) |
| (parallelism TS v2) |
simd_mask を最初または最後の true 値のインデックスにリダクションする (関数テンプレート) |
[編集] トレイト
| (parallelism TS v2) |
型が simd または simd_mask 型であるかをチェックする (クラステンプレート) |
| (parallelism TS v2) |
型がABIタグ型であるかをチェックする (クラステンプレート) |
| (parallelism TS v2) |
型がsimdフラグ型であるかをチェックする (クラステンプレート) |
| (parallelism TS v2) |
与えられた要素型とABIタグの要素数を取得する (クラステンプレート) |
| (parallelism TS v2) |
vector_aligned のための適切なアライメントを取得する (クラステンプレート) |
| (parallelism TS v2) |
simd または simd_mask の要素型または要素数を変更する (クラステンプレート) |
[編集] 数学関数
<cmath> 内のすべての関数は、特殊数学関数を除き、simd に対してオーバーロードされます。
[編集] 例
#include <experimental/simd> #include <iostream> #include <string_view> namespace stdx = std::experimental; void println(std::string_view name, auto const& a) { std::cout << name << ": "; for (std::size_t i{}; i != std::size(a); ++i) std::cout << a[i] << ' '; std::cout << '\n'; } template<class A> stdx::simd<int, A> my_abs(stdx::simd<int, A> x) { where(x < 0, x) = -x; return x; } int main() { const stdx::native_simd<int> a = 1; println("a", a); const stdx::native_simd<int> b([](int i) { return i - 2; }); println("b", b); const auto c = a + b; println("c", c); const auto d = my_abs(c); println("d", d); const auto e = d * d; println("e", e); const auto inner_product = stdx::reduce(e); std::cout << "inner product: " << inner_product << '\n'; const stdx::fixed_size_simd<long double, 16> x([](int i) { return i; }); println("x", x); println("cos²(x) + sin²(x)", stdx::pow(stdx::cos(x), 2) + stdx::pow(stdx::sin(x), 2)); }
出力
a: 1 1 1 1 b: -2 -1 0 1 c: -1 0 1 2 d: 1 0 1 2 e: 1 0 1 4 inner product: 6 x: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 cos²(x) + sin²(x): 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[編集] 関連項目
| 数値配列、配列マスク、および配列スライス (クラステンプレート) |
[編集] 外部リンク
| 1. | ISO/IEC TS 19570:2018 Section 9 "Data-Parallel Types" の実装 — github.com |
| 2. | GCC/libstdc++ のTS実装状況 (std::experimental::simd は GCC-11 に同梱) — gcc.gnu.org |