命名空间
变体
操作

SIMD 库

来自 cppreference.cn
< cpp‎ | 实验性
 
 
实验性
技术规范
文件系统库 (文件系统 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>

目录

[编辑] 主类

(并行技术规范 v2)
数据并行向量类型
(类模板) [编辑]
(并行技术规范 v2)
元素类型为 bool 的数据并行类型
(类模板) [编辑]

[编辑] ABI 标签

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

[编辑] 对齐标签

指示加载/存储地址对齐到元素对齐的标志
(类) [编辑]
(并行技术规范 v2)
指示加载/存储地址对齐到向量对齐的标志
(类) [编辑]
(并行技术规范 v2)
指示加载/存储地址对齐到指定对齐的标志
(类模板) [编辑]

[编辑] Where 表达式

(并行技术规范 v2)
通过非变异操作选择的元素
(类模板)
(并行技术规范 v2)
通过变异操作选择的元素
(类模板)
(并行技术规范 v2)
生成 const_where_expression 和 where_expression
(函数模板)

[编辑] 类型转换

(并行技术规范 v2)
逐元素 static_cast
(函数模板)
逐元素 ABI 类型转换
(函数模板)
(并行技术规范 v2)
将单个 simd 对象拆分为多个对象
(函数模板)
(并行技术规范 v2)
将多个 simd 对象连接成一个对象
(函数模板)

[编辑] 算法

(并行技术规范 v2)
逐元素最小值操作
(函数模板)
(并行技术规范 v2)
逐元素最大值操作
(函数模板)
(并行技术规范 v2)
逐元素最小-最大操作
(函数模板)
(并行技术规范 v2)
逐元素钳制操作
(函数模板)

[编辑] 归约

(并行技术规范 v2)
将向量归约到单个元素
(函数模板)

[编辑] 掩码归约

(并行技术规范 v2)
simd_mask 归约到 bool
(函数模板) [编辑]
(并行技术规范 v2)
simd_mask 归约到 true 值的数量
(函数模板) [编辑]
(并行技术规范 v2)
simd_mask 归约到第一个或最后一个 true 值的索引
(函数模板) [编辑]

[编辑] 特性

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