パッケージjdk.incubator.vector
インキュベート機能。 将来のリリースで削除されます。
このパッケージは、適切なハードウェアおよび実行時機能が与えられた場合にベクトル・ハードウェア命令を使用して高速化されるベクトル計算を表すクラスを提供します。
「ベクトル」は
byte
、long
、float
などの一部の固定「要素型」である、固定数の「レーン」の順序。 各レーンには、要素タイプの独立した値が含まれます。 ベクトルに対する演算は通常レーンワイズであり、一部のスカラー演算子(「加算」など)が参加ベクトルのレーンに分散され、通常、レーンに様々なスカラー結果が含まれるベクトル結果が生成されます。 サポートしているプラットフォームで実行すると、ハードウェアでレーンワイズ演算をパラレルに実行できます。 この並列度スタイルは、「単一指図複数データ」 (SIMD)並列度と呼ばれます。
SIMD形式のプログラミングでは、ベクトル・レーン内のほとんどの演算は無条件ですが、関連付けられたVectorMask
の制御下で、blend()
などの「マスクされた演算」を使用して条件付き実行の効果を得ることができます。 厳密にレーンワイズ・フロー以外のデータ移動は、多くの場合、関連するVectorShuffle
の制御下で、クロスレーン演算を使用して実現されます。 レーン・データまたはベクトル全体(あるいはその両方)は、様々な種類のレーンワイズ「変換」またはバイト単位の再フォーマットreinterpretationsを使用して再フォーマットでき、多くの場合、入力ベクトルとは異なる代替ベクトル・フォーマットを選択する反射VectorSpecies
オブジェクトの制御下で再フォーマットされます。
Vector<E>
では、すべての要素タイプに共通のベクトル演算(メソッド)のセットを宣言します。 これらの一般的な演算には、レーン値への汎用アクセス、データの選択と移動、再フォーマット、およびすべてのプリミティブ型に共通する特定の算術演算子と論理演算子の(加算や比較など)が含まれます。
「Vector
のパブリック・サブタイプ」は、特定の要素タイプに対応します。 これらは、レーン値へのボックス化されていないアクセス、整数要素型の値に対するビット単位の演算、浮動小数点要素型の値に対するトランザクション演算など、その要素型に固有のさらなる演算を宣言します。
add
演算子などの一部のレーンワイズ演算は、フル・サービス名前付き演算として定義されます。この場合、Vector
の対応するメソッドはマスキングされたオーバーロードおよびマスキングされていないオーバーロードになり、(サブクラス)は(サブクラスを返す)および追加のスカラー・ブロードキャスト・オーバーロード(マスク済とマスク解除済の両方)もオーバーライドします。 min
演算子などのその他のレーンワイズの演算は、部分的にサービスされる(フル・サービスではありません)名前付き演算として定義されます。ここでは、Vector
またはサブクラス(あるいはその両方)の対応するメソッドによって、可能性のあるすべてのオーバーロードが提供され、(一般的に、スカラー・ブロード・キャストの過負荷を伴うマスクされていないバリアント)がオーバーライドされます。 最後に、レーンワイズすべての演算の(前述のように指定されたもの、または名前のないメソッドに関するもの)には、対応するoperator token
がVectorOperators
で静的定数として宣言されています。 各演算子トークンは、ADD
演算子トークン用のa + b
など、演算のシンボリックJava式を定義します。 「単項レーンワイズ」演算などの一般的なレーンワイズ演算トークン受入れメソッドは、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
配列要素のtailを処理するために必要です。ここで、TLENGTH < SPECIES.length()
はベクトルの種を表します。 前述の例では、優先する種の(FloatVector.SPECIES_PREFERRED
)を使用して、コードが実行されるプラットフォームに最適なシェイプに動的に適応するようにしています。
前述のコードでは、ヘルパー・メソッドloopBound()
を使用してベクトル・ループの終了を検索します。 SPECIES.length()
は8(2の累乗)であることがわかっているため、ここでは(a.length & ~(SPECIES.length() - 1))
などのプリミティブ・マスキング式も使用できます。 ただし、これは必ずしも正しい前提ではありません。 たとえば、FloatVector.SPECIES_PREFERRED
がプラットフォーム依存のシェイプS_Max_BIT
を持ち、そのシェイプに384 (これは、一部のアーキテクチャに従った有効なベクトル・サイズです)などの奇数の仮説サイズがある場合、ハンド弱いプリミティブ・マスキング式によって驚くべき結果が生成される可能性があります。
評価ノート
このパッケージは、ベクトル演算を最適なベクトル・ハードウェア命令に動的にコンパイルするランタイム機能に依存します。 演算をベクトル命令にコンパイルできない場合に使用される、各演算のデフォルトのスカラー実装があります。最適なベクトル・マシン・コードを生成するには、ユーザーが注意する必要がある特定の事項があります:
- 使用するベクトルのシェイプは、基礎となるプラットフォームでサポートされている必要があります。 たとえば、
VectorShape
S_512_BIT
のIntVector
を使用して記述されたコードは、256ビットのベクトルのみをサポートするプラットフォームではベクトル命令にコンパイルされません。 かわりに、デフォルトのスカラー実装が使用されます。 このため、一般的なサイズのベクトル計算を記述するには、上記の優先種を使用することをお勧めします。 - このパッケージで定義されているほとんどのクラスは、value-basedクラスとして処理する必要があります。 この分類は、
Vector
とそのサブタイプであるVectorMask
、VectorShuffle
およびVectorSpecies
に適用されます。 これらのタイプでは、次のようになります。==
などのアイデンティティ依存の演算では、予期しない結果が発生したり、パフォーマンスが低下する可能性があります。equals
はアイデンティティ依存のメソッドではないため、v.equals(w)
はv==w
よりも高速である可能性が高くなります。 また、これらのオブジェクトは、ローカルおよびパラメータにもstatic final
定数としても格納できますが、意味的には有効ですが、他のJavaフィールドまたは配列要素に格納すると、パフォーマンス・リスクが発生する可能性があります。
このパッケージのすべてのクラスについて、特に指定されていないかぎり、参照型のメソッド引数はnullにできず、null引数はNullPointerException
を列挙します。 このファクトは、このAPIのメソッドについて個別には記載されていません。
-
クラス説明順序付けられた不変の
byte
値のシーケンスを表す特殊なVector
。順序付けられた不変のdouble
値のシーケンスを表す特殊なVector
。順序付けられた不変のfloat
値のシーケンスを表す特殊なVector
。順序付けられた不変のint
値のシーケンスを表す特殊なVector
。順序付けられた不変のlong
値のシーケンスを表す特殊なVector
。順序付けられた不変のshort
値のシーケンスを表す特殊なVector
。Vector<E>Abyte
、long
、float
などの一部の固定「要素型」である、固定数の「レーン」の順序。VectorMask<E>VectorMask
は、順序付けられた不変のboolean
値のシーケンスを表します。このクラスは、レーンワイズ・ベクトル演算を記述するstatic定数と、それらを分類する入れ子のインタフェースだけで構成されます。すべての再関連付けレーンワイズ二項演算子のタイプで、e = v0.
reduceLanes
(ADD)
などの式で使用できます。引数、引数および戻り型、シンボリック名、演算子名などの共通プロパティの問合せを提供する、すべての演算子トークンのルート・タイプ。VectorShape
は、Vector
の特定の実装を選択します。VectorShuffle
は、「ソース索引」と呼ばれる、順序付けされた不変の一連のint
値を表します。各ソース索引は、互換性のあるVector
からソース・レーンを数値で選択します。