Namespaces
Variants

SIMD library

From cppreference.net

Библиотека 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_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>;
Код C++ оставлен без изменений, как и требовалось. HTML-теги и атрибуты сохранены в оригинальном виде.

Это гарантирует, что набор типов имеет одинаковую ширину и, следовательно, может быть преобразован. Преобразование с несовпадающей шириной не определено, поскольку оно либо приведет к потере значений, либо потребует создания значений. Для операций изменения размера библиотека SIMD предоставляет функции split и concat .

Определено в заголовке <experimental/simd>

Содержание

Основные классы

(parallelism TS v2)
тип вектора с параллелизмом данных
(шаблон класса)
(parallelism TS v2)
тип с параллелизмом данных с типом элементов bool
(шаблон класса)

Теги ABI

Определено в пространстве имен 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)
поэлементная операция min
(шаблон функции)
(parallelism TS v2)
поэлементная операция max
(шаблон функции)
(parallelism TS v2)
поэлементная операция minmax
(шаблон функции)
(parallelism TS v2)
поэлементная операция clamp
(шаблон функции)

Редукция

(parallelism TS v2)
сводит вектор к одному элементу
(шаблон функции)

Редукция маски

редукции simd_mask в bool
(шаблон функции)
(parallelism TS v2)
редукция simd_mask в количество true значений
(шаблон функции)
(parallelism TS v2)
редукции simd_mask в индекс первого или последнего true значения
(шаблон функции)

Трейты

(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. Реализация раздела 9 "Типы с параллелизмом данных" ISO/IEC TS 19570:2018 — github.com
2. Реализация TS доступна для GCC/libstdc++ ( std::experimental::simd поставляется с GCC-11) — gcc.gnu.org