命名空间
变体
操作

SIMD 库

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

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)
用于存储单个元素的标签类型
(typedef) [编辑]
(并行 TS v2)
用于存储指定数量元素的标签类型
(别名模板)[编辑]
(并行 TS v2)
确保 ABI 兼容性的标签类型
(别名模板)[编辑]
(并行 TS v2)
效率最高的标签类型
(别名模板)[编辑]
(并行 TS v2)
固定支持的元素数量的最大值
(常量) [编辑]
(并行 TS v2)
获取给定元素类型和元素数量的 ABI 类型
(类模板) [编辑]

[编辑] 对齐标签

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

[编辑] Where 表达式

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

[编辑] 强制转换

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

[编辑] 算法

(并行 TS v2)
逐元素最小值运算
(函数模板)
(并行 TS v2)
逐元素最大值运算
(函数模板)
(并行 TS v2)
逐元素最小值和最大值运算
(函数模板)
(并行 TS v2)
逐元素钳位运算
(函数模板)

[编辑] 归约

(并行 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 的适当对齐
(类模板) [编辑]
更改 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