命名空间
变体
操作

SIMD 库

出自 cppreference.cn
 
 
实验性
技术规范
文件系统库 (文件系统 TS)
库基础 (库基础 TS)
库基础 2 (库基础 TS v2)
库基础 3 (库基础 TS v3)
并行性扩展 (并行性 TS)
并行性扩展 2 (并行性 TS v2)
并发性扩展 (并发性 TS)
并发性扩展 2 (并发性 TS v2)
概念 (概念 TS)
范围 (范围 TS)
反射 (反射 TS)
数学特殊函数 (特殊函数 TR)
实验性非 TS
模式匹配
线性代数
std::execution
契约
2D 图形
 
 
 

SIMD 库为显式声明数据并行性和构造数据以实现更高效的 SIMD 访问提供了可移植的类型。

类型 simd<T> 的对象行为类似于类型 T 的对象。但是,虽然 T 存储和操作单个值,但 simd<T> 存储和操作多个值(称为宽度,但为了与标准库的其余部分保持一致,标识为 size;参见 simd_size)。

simd<T> 上的每个运算符和操作都逐元素执行(水平操作除外,这些操作已明确标记)。这个简单的规则表达了数据并行性,编译器将使用它来生成 SIMD 指令和/或独立的执行流。

类型 simd<T>native_simd<T> 的宽度由实现方式在编译时确定。 相比之下,类型 fixed_size_simd<T, N> 的宽度由开发人员固定为特定大小。

使用不同 SIMD 类型混合以获得高效率的推荐模式是使用 native_simdrebind_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 库提供了 splitconcat 函数。

定义于头文件 <experimental/simd>

目录

[编辑] 主要类

(并行性 TS v2)
数据并行向量类型
(类模板) [编辑]
(并行性 TS v2)
元素类型为 bool 的数据并行类型
(类模板) [编辑]

[编辑] ABI 标签

定义于命名空间 std::experimental::simd_abi
(并行性 TS v2)
用于存储单个元素的标签类型
(类型别名) [编辑]
(并行性 TS v2)
用于存储指定数量元素的标签类型
(别名模板)[编辑]
(并行性 TS v2)
确保 ABI 兼容性的标签类型
(别名模板)[编辑]
(并行性 TS v2)
最高效的标签类型
(别名模板)[编辑]
(并行性 TS v2)
保证 fixed 支持的最大元素数量
(常量) [编辑]
(并行性 TS v2)
获取给定元素类型和元素数量的 ABI 类型
(类模板) [编辑]

[编辑] 对齐标签

标志,指示加载/存储地址到元素对齐的对齐方式
(类) [编辑]
标志,指示加载/存储地址到向量对齐的对齐方式
(类) [编辑]
标志,指示加载/存储地址到指定对齐量的对齐方式
(类模板) [编辑]

[编辑] Where 表达式

(并行性 TS v2)
使用非变异操作选择元素
(类模板)
(并行性 TS v2)
使用变异操作选择元素
(类模板)
(并行性 TS v2)
产生 const_where_expression 和 where_expression
(函数模板)

[编辑] 类型转换

逐元素 static_cast
(函数模板)
逐元素 ABI 转换
(函数模板)
(并行性 TS v2)
将单个 simd 对象拆分为多个对象
(函数模板)
(并行性 TS v2)
将多个 simd 对象连接成一个对象
(函数模板)

[编辑] 算法

(并行性 TS v2)
逐元素 min 操作
(函数模板)
(并行性 TS v2)
逐元素 max 操作
(函数模板)
(并行性 TS v2)
逐元素 minmax 操作
(函数模板)
(并行性 TS v2)
逐元素 clamp 操作
(函数模板)

[编辑] 归约

(并行性 TS v2)
将向量归约为单个元素
(函数模板)

[编辑] 掩码归约

simd_mask 归约为 bool
(函数模板) [编辑]
(并行性 TS v2)
simd_mask 归约为 true 值的数量
(函数模板) [编辑]
simd_mask 归约为第一个或最后一个 true 值的索引
(函数模板) [编辑]

[编辑] 特征

(并行性 TS v2)
检查类型是否为 simdsimd_mask 类型
(类模板) [编辑]
(并行性 TS v2)
检查类型是否为 ABI 标签类型
(类模板) [编辑]
(并行性 TS v2)
检查类型是否为 simd 标志类型
(类模板) [编辑]
(并行性 TS v2)
获取给定元素类型和 ABI 标签的元素数量
(类模板) [编辑]
(并行性 TS v2)
vector_aligned 获取适当的对齐量
(类模板) [编辑]
(并行性 TS v2)
更改 simdsimd_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