Spec-Zone.ru › OpenJDK 24

Пакет jdk.incubator.vector

package jdk.incubator.vector

Экспериментальная функция. Будет удалена в будущей версии.

Этот пакет предоставляет классы для выражения векторных вычислений, которые, при наличии соответствующего оборудования и возможностей среды выполнения, ускоряются с помощью векторных инструкций процессора.

Вектор представляет собой последовательность фиксированного числа элементов, каждый из которых имеет фиксированный тип элемента, например, byte, long или float. Каждый элемент содержит независимое значение типа элемента. Операции над векторами, как правило, выполняются поэлементно, распределяя некоторый скалярный оператор (например, сложение) по элементам участвующих векторов, обычно генерируя результирующий вектор, элементы которого содержат различные скалярные результаты. При выполнении на поддерживающей платформе поэлементные операции могут выполняться параллельно аппаратными средствами. Этот стиль параллелизма называется параллелизмом Single Instruction Multiple Data (SIMD).

В стиле программирования SIMD большинство операций внутри элемента вектора выполняются безусловно, но эффект условного выполнения может быть достигнут с помощью маскированных операций, таких как blend(), под управлением связанной VectorMask. Перемещение данных, отличное от строго поэлементного потока, достигается с помощью операций между элементами, часто под управлением связанного VectorShuffle. Данные элементов и/или целые векторы могут быть переформатированы с помощью различных видов преобразований поэлементного преобразования преобразований и преобразования байтового формата переинтерпретаций, часто под управлением рефлексивного VectorSpecies объекта, который выбирает альтернативный формат вектора, отличный от формата входного вектора.

Vector<E> объявляет набор векторных операций (методов), которые являются общими для всех типов элементов. Эти общие операции включают общий доступ к значениям элементов, выбор и перемещение данных, переформатирование и некоторые арифметические и логические операции (например, сложение или сравнение), которые являются общими для всех примитивных типов.

Подтипы Vector соответствуют конкретным типам элементов. Они объявляют дополнительные операции, специфичные для этого типа элемента, включая разворачивание доступа к значениям элементов, побитовые операции над значениями целых типов элементов или трансцендентные операции над значениями с плавающей точкой.

Некоторые поэлементные операции, такие как оператор add, определены как полная операция с именем, где соответствующий метод в Vector доступен в перегрузках с масками и без них, а также (в подтипах) в ковариантных переопределениях (возвращающих подтип) и дополнительных перегрузках с передачей скалярного значения (с масками и без них). Другие поэлементные операции, такие как оператор min, определены как частично реализованная (не полная) операция с именем, где соответствующий метод в Vector и/или подтипе предоставляет некоторые, но не все возможные перегрузки и переопределения (обычно вариант без маски со скалярными перегрузками). Наконец, все поэлементные операции (именованные как описано ранее или определенные через метод) имеют соответствующий operator token, объявленный как статическая константа в VectorOperators. Каждый оператор определяет символическое Java-выражение для операции, например, a + b для оператора ADD. Общие методы, принимающие токены поэлементных операций, например, для поэлементной операции типа "унарной", предоставляются в Vector и имеют те же варианты, что и полная операция с именем.

Этот пакет содержит публичный подтип Vector, соответствующий каждому поддерживаемому типу элемента: ByteVector, ShortVector, IntVector, LongVector, FloatVector и DoubleVector.

Вот пример умножения элементов двух массивов float a и b с помощью векторных вычислений и сохранения результата в массиве c.


 static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_PREFERRED;

 void vectorMultiply(float[] a, float[] b, float[] c) {
   // It is assumed array arguments are of the same size
   for (int i = 0; i < a.length; i += SPECIES.length()) {
         VectorMask<Float> m = SPECIES.indexInRange(i, a.length);
         FloatVector va = FloatVector.fromArray(SPECIES, a, i, m);
         FloatVector vb = FloatVector.fromArray(SPECIES, b, i, m);
         FloatVector vc = va.mul(vb)
         vc.intoArray(c, i, m);
   }
 }
 
В приведенном выше примере мы используем маски, сгенерированные с помощью indexInRange(), для предотвращения чтения/записи за пределами длины массива. В первых a.length / SPECIES.length() итерациях маска будет содержать все единицы. Только в последней итерации (если a.length не кратно SPECIES.length()) маска будет содержать единицы только в первых a.length % SPECIES.length() элементах. Поскольку маска используется во всех итерациях, данная реализация может не обеспечить оптимальную производительность (для больших длин массивов). То же самое вычисление можно реализовать без масок следующим образом:

 static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_PREFERRED;

 void vectorMultiply(float[] a, float[] b, float[] c) {
   int i = 0;
   // It is assumed array arguments are of the same size
   for (; i < SPECIES.loopBound(a.length); i += SPECIES.length()) {
         FloatVector va = FloatVector.fromArray(SPECIES, a, i);
         FloatVector vb = FloatVector.fromArray(SPECIES, b, i);
         FloatVector vc = va.mul(vb)
         vc.intoArray(c, i);
   }

   for (; i < a.length; i++) {
     c[i] = a[i] * b[i];
   }
 }
 
Скалярное вычисление после векторного вычисления требуется для обработки остатка элементов массива TLENGTH, где TLENGTH < SPECIES.length() для вида вектора. Приведенные выше примеры используют предпочтительный вид вектора (FloatVector.SPECIES_PREFERRED), обеспечивая динамическую адаптацию кода к оптимальной форме для платформы, на которой он выполняется.

В приведенном коде используется вспомогательный метод loopBound() для определения конца цикла векторов. Также здесь может быть использовано примитивное выражение маскирования, например, (a.length & ~(SPECIES.length() - 1)), так как известно, что SPECIES.length() равно 8, что является степенью двойки. Но это не всегда верное предположение. Например, если FloatVector.SPECIES_PREFERRED оказывается иметь платформозависимую форму S_Max_BIT, и эта форма имеет некоторую странную гипотетическую величину, например 384 (что является допустимым размером вектора в соответствии с некоторыми архитектурами), то ручное выражение маскирования может привести к неожиданным результатам.

Примечания по производительности

Этот пакет зависит от способности среды выполнения динамически компилировать векторные операции в оптимальные векторные инструкции процессора. Для каждой операции имеется по умолчанию скалярная реализация, которая используется, если операция не может быть скомпилирована в векторные инструкции.

Пользователям следует обратить внимание на следующие моменты для генерации оптимального векторного кода:

  • Форма используемых векторов должна поддерживаться подлежащей платформой. Например, код, написанный с использованием IntVector вида VectorShape S_512_BIT, не будет скомпилирован в векторные инструкции на платформе, которая поддерживает только векторы размером 256 бит. Вместо этого будет использоваться реализация по умолчанию. По этой причине рекомендуется использовать предпочтительный вид вектора, как показано выше, для написания векторных вычислений с общим размером.
  • Большинство классов, определенных в этом пакете, следует рассматривать как классы, основанные на значениях. Это относится к Vector и его подтипам, VectorMask, VectorShuffle и VectorSpecies. С этими типами, операции, чувствительные к идентичности, такие как ==, могут давать непредсказуемые результаты или снижать производительность. Удивительно, что v.equals(w) вероятно будет быстрее, чем v==w, поскольку equals не является методом, чувствительным к идентичности. Также эти объекты могут храниться в локальных переменных и параметрах, а также как static final константы, но хранение их в других полях Java или в элементах массива, хотя и семантически допустимо, может повлечь за собой риски для производительности.

Для каждого класса в этом пакете, если не указано иное, любые аргументы метода ссылочного типа не должны быть null, и любой null-аргумент вызовет NullPointerException. Этот факт не документируется отдельно для методов этого API.

Класс Описание
ByteVector
Специализированная Vector, представляющая упорядоченную неизменяемую последовательность byte значений.
DoubleVector
Специализированная Vector, представляющая упорядоченную неизменяемую последовательность double значений.
Float16
Класс Float16 хранит 16-битные данные в формате IEEE 754 binary16.
FloatVector
Специализированная Vector, представляющая упорядоченную неизменяемую последовательность float значений.
IntVector
Специализированная Vector, представляющая упорядоченную неизменяемую последовательность int значений.
LongVector
Специализированная Vector, представляющая упорядоченную неизменяемую последовательность long значений.
ShortVector
Специализированная Vector, представляющая упорядоченную неизменяемую последовательность short значений.
Vector<E>
Последовательность фиксированного числа ланей, все из которых имеют один и тот же фиксированный тип элемента, например byte, long или float.
VectorMask<E>
VectorMask представляет упорядоченную неизменяемую последовательность boolean значений.
VectorMath
Класс VectorMath содержит методы для выполнения скалярных числовых операций в поддержку векторных числовых операций.
VectorOperators
Этот класс состоит только из статических констант, описывающих операции над векторами по ланям, а также вложенных интерфейсов, которые их классифицируют.
VectorOperators.Associative
Тип для всех реассоциирующих поэлементных бинарных операторов, применимых в выражениях типа e = v0.reduceLanes(ADD).
VectorOperators.Binary
Тип для всех поэлементных бинарных (двухаргументных) операторов, применимых в выражениях типа w = v0.lanewise(ADD, v1).
VectorOperators.Comparison
Тип для всех бинарных поэлементных булевых сравнений значений ланей, применимых в выражениях типа m = v0.compare(LT, v1).
VectorOperators.Conversion<E,F>
Тип для всех поэлементных преобразований значений ланей, применимых в выражениях типа w1 = v0.convert(I2D, 1).
VectorOperators.Operator
Основной тип для всех операторных токенов, предоставляющий запросы для общих свойств, таких как арность, типы аргументов и возвращаемого значения, символьное имя и имя оператора.
VectorOperators.Ternary
Тип для всех поэлементных тернарных (трехаргументных) операторов, применимых в выражениях типа w = v0.lanewise(FMA, v1, v2).
VectorOperators.Test
Тип для всех унарных поэлементных булевых проверок значений ланей, применимых в выражениях типа m = v0.test(IS_FINITE).
VectorOperators.Unary
Тип для всех поэлементных унарных (одноаргументных) операторов, применимых в выражениях типа w = v0.lanewise(NEG).
VectorShape
VectorShape выбирает определённую реализацию Vector.
VectorShuffle<E>
VectorShuffle представляет упорядоченную неизменяемую последовательность int значений, называемых индексами источника, где каждый индекс источника численно выбирает целевую лань из совместимого Vector.
VectorSpecies<E>
Интерфейс для управления всеми векторами с одинаковой комбинацией типа элемента (ETYPE) и shape.

© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://download.java.net/java/early_access/jdk24/docs/api/jdk.incubator.vector/jdk/incubator/vector/package-summary.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API