名稱空間
變體
操作

SIMD 庫

來自 cppreference.com
< 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