Spec-Zone.ru › OpenJDK 25

Пакет jdk.incubator.vector

package jdk.incubator.vector

Инкубируемая функция. Будет удалена в одном из будущих выпусков.

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

Вектор — это последовательность фиксированного числа элементов, имеющих один фиксированный тип элемента, например byte, long или float. Каждый элемент содержит независимое значение типа элемента. Операции над векторами обычно выполняются поэлементно: скалярный оператор (например, сложение) применяется ко всем элементам участвующих векторов, обычно создавая вектор-результат, элементы которого содержат соответствующие скалярные результаты. На поддерживающей платформе поэлементные операции могут выполняться аппаратурой параллельно. Такой вид параллелизма называется параллелизмом одной инструкции и множества данных (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.

Ниже приведён пример умножения элементов двух массивов чисел с плавающей точкой 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.

Сообщить об ошибке или предложить улучшение
Дополнительные справочные материалы по API и документацию для разработчиков см. в документации Java SE, содержащей более подробные описания для разработчиков, обзоры концепций, определения терминов, обходные решения и работающие примеры кода. Другие версии.
Java является товарным знаком или зарегистрированным товарным знаком Oracle и/или её аффилированных лиц в США и других странах.
Авторские права © 1993, 2025, Oracle и/или её аффилированные лица, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
Все права защищены. Использование регулируется условиями лицензии и политикой распространения документации.

© 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://docs.oracle.com/en/java/javase/25/docs/api/jdk.incubator.vector/jdk/incubator/vector/package-summary.html

Spec-Zone.ru

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