Namespaces
Variants

SIMD library

From cppreference.net

SIMDライブラリは、データ並列性を明示的に宣言するためのポータブルな型と、より効率的なSIMDアクセスのためのデータ構造を提供します。

simd<T> 型のオブジェクトは、 T 型のオブジェクトと同様に振る舞います。ただし、 T が1つの値を格納・操作するのに対し、 simd<T> は複数の値( width と呼ばれるが、標準ライブラリの他の部分との一貫性のために size として識別される; simd_size 参照)を格納・操作します。

simd<T> 上のすべての演算子と操作は(明示的に 水平 操作と記されているものを除き) 要素単位 で動作します。この単純なルールはデータ並列性を表現し、コンパイラによって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)
データ並列ベクトル型
(クラステンプレート)
(parallelism TS v2)
要素型がboolのデータ並列型
(クラステンプレート)

ABI タグ

namespace std::experimental::simd_abi で定義
(parallelism TS v2)
単一要素を格納するためのタグ型
(typedef)
(parallelism TS v2)
指定された数の要素を格納するためのタグ型
(alias template)
(parallelism TS v2)
ABI互換性を保証するタグ型
(alias template)
(parallelism TS v2)
最も効率的なタグ型
(alias template)
(parallelism TS v2)
fixedでサポートされることが保証される最大要素数
(constant)
(parallelism TS v2)
指定された要素型と要素数に対するABI型を取得する
(class template)

アライメントタグ

ロード/ストアアドレスの要素アライメントを示すフラグ
(クラス)
ロード/ストアアドレスのベクトルアライメントを示すフラグ
(クラス)
(parallelism TS v2)
ロード/ストアアドレスの指定されたアライメントを示すフラグ
(クラステンプレート)

Where式

(parallelism TS v2)
非変更操作による選択された要素
(クラステンプレート)
(parallelism TS v2)
変更操作による選択された要素
(クラステンプレート)
(parallelism TS v2)
const_where_expression と where_expression を生成
(関数テンプレート)

キャスト

(parallelism TS v2)
要素ごとのstatic_cast
(関数テンプレート)
要素ごとのABIキャスト
(関数テンプレート)
(parallelism TS v2)
単一のsimdオブジェクトを複数に分割
(関数テンプレート)
(parallelism TS v2)
複数のsimdオブジェクトを単一に連結
(関数テンプレート)

アルゴリズム

(parallelism TS v2)
要素単位の最小値演算
(関数テンプレート)
(parallelism TS v2)
要素単位の最大値演算
(関数テンプレート)
(parallelism TS v2)
要素単位の最小値・最大値演算
(関数テンプレート)
(parallelism TS v2)
要素単位のクランプ演算
(関数テンプレート)

リダクション

(parallelism TS v2)
ベクトルを単一の要素に縮約する
(関数テンプレート)

マスク削減

simd_mask の リダクションを bool
(関数テンプレート)
(parallelism TS v2)
simd_mask true 値の数への リダクション
(関数テンプレート)
(parallelism TS v2)
simd_mask の 最初または最後の true 値の インデックスへのリダクション
(関数テンプレート)

Traits

(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 セクション9「データ並列型」の実装 — github.com
2. TS実装の到達状況: GCC/libstdc++ ( std::experimental::simd GCC-11で出荷) — gcc.gnu.org