Пакет 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изVectorShapeS_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, |
Тип для всех преобразований значений элементов, выполняемых поэлементно и используемых в выражениях, например 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> |
© 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