モジュール jdk.incubator.vector

パッケージjdk.incubator.vector


パッケージjdk.incubator.vector

「インキュベート機能」
将来のリリースで削除されます。

このパッケージは、適切なハードウェアおよび実行時機能が与えられた場合にベクトル・ハードウェア命令を使用して高速化されるベクトル計算を表すクラスを提供します。

ベクトル bytelongfloatなどの一部の固定要素型である、固定数の「レーン」の順序。 各レーンには、要素タイプの独立した値が含まれます。 ベクトルに対する演算は通常レーンワイズであり、一部のスカラー演算子(「加算」など)が参加ベクトルのレーンに分散され、通常、レーンに様々なスカラー結果が含まれるベクトル結果が生成されます。 サポートしているプラットフォームで実行すると、ハードウェアでレーンワイズ演算をパラレルに実行できます。 この並列度スタイルは、「単一指図複数データ」 (SIMD)並列度と呼ばれます。

SIMD形式のプログラミングでは、ベクトル・レーン内のほとんどの演算は無条件ですが、関連付けられたVectorMaskの制御下で、blend()などのマスクされた演算を使用して条件付き実行の効果を得ることができます。 厳密にレーンワイズ・フロー以外のデータ移動は、多くの場合、関連するVectorShuffleの制御下で、クロスレーン演算を使用して実現されます。 レーン・データまたはベクトル全体(あるいはその両方)は、様々な種類のレーンワイズ「変換」またはバイト単位の再フォーマットreinterpretationsを使用して再フォーマットでき、多くの場合、入力ベクトルとは異なる代替ベクトル・フォーマットを選択する反射VectorSpeciesオブジェクトの制御下で再フォーマットされます。

Vector<E>では、すべての要素タイプに共通のベクトル演算(メソッド)のセットを宣言します。 これらの一般的な演算には、レーン値への汎用アクセス、データの選択と移動、再フォーマット、およびすべてのプリミティブ型に共通する特定の算術演算子と論理演算子の(加算や比較など)が含まれます。

Vectorのパブリック・サブタイプ」は、特定の要素タイプに対応します。 これらは、レーン値へのボックス化されていないアクセス、整数要素型の値に対するビット単位の演算、浮動小数点要素型の値に対するトランザクション演算など、その要素型に固有のさらなる演算を宣言します。

add演算子などの一部のレーンワイズ演算は、フル・サービス名前付き演算として定義されます。この場合、Vectorの対応するメソッドはマスキングされたオーバーロードおよびマスキングされていないオーバーロードになり、(サブクラス)は(サブクラスを返す)および追加のスカラー・ブロードキャスト・オーバーロード(マスク済とマスク解除済の両方)もオーバーライドします。 min演算子などのその他のレーンワイズの演算は、部分的にサービスされる(フル・サービスではありません)名前付き演算として定義されます。ここでは、Vectorまたはサブクラス(あるいはその両方)の対応するメソッドによって、可能性のあるすべてのオーバーロードが提供され、(一般的に、スカラー・ブロードキャスト・オーバーロードのあるマスクされていない可変)がオーバーライドされます。 最後に、レーンワイズすべての演算の(前述のように指定されたもの、または名前のないメソッドに関するもの)には、対応するoperator tokenVectorOperatorsで静的定数として宣言されています。 各演算子トークンは、ADD演算子トークン用のa + bなど、演算のシンボリックJava式を定義します。 「単項レーンワイズ」演算などの一般的なレーンワイズ演算トークン受入れメソッドは、Vectorで提供され、フル・サービス名前付き演算と同じバリアントになります。

このパッケージには、サポートされている各要素タイプに対応するVectorのパブリック・サブタイプが含まれます: ByteVectorShortVectorIntVectorLongVectorFloatVectorおよび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.lengthSPECIES.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_BITIntVectorを使用して記述されたコードは、256ビットのベクトルのみをサポートするプラットフォームではベクトル命令にコンパイルされません。 かわりに、デフォルトのスカラー実装が使用されます。 このため、一般的なサイズのベクトル計算を記述するには、上記の優先種を使用することをお勧めします。
  • このパッケージで定義されているほとんどのクラスは、value-basedクラスとして処理する必要があります。 この分類は、VectorとそのサブタイプであるVectorMaskVectorShuffleおよび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
    A bytelongfloatなどの一部の固定要素型である、固定数の「レーン」の順序。
    VectorMaskは、順序付けられた不変のboolean値のシーケンスを表します。
    このクラスは、レーンワイズ・ベクトル演算を記述するstatic定数と、それらを分類する入れ子のインタフェースだけで構成されます。
    すべての再関連付けレーンワイズ二項演算子のタイプで、e = v0. reduceLanes(ADD)などの式で使用できます。
    w = v0. lanewise(ADD, v1)などの式で使用可能な、すべてのレーンワイズ二項(2引数)演算子のタイプ。
    レーン値に対するすべての二項レーンワイズ・ブール比較のタイプで、m = v0. compare(LT, v1)などの式で使用できます。
    レーン値のすべてのレーンワイズ変換のタイプで、w1 = v0. convert(I2D, 1)などの式で使用できます。
    引数、引数および戻り型、シンボリック名、演算子名などの共通プロパティの問合せを提供する、すべての演算子トークンのルート・タイプ。
    すべてのレーンワイズ三項(3引数)演算子のタイプで、w = v0. lanewise(FMA, v1, v2)などの式で使用できます。
    レーン値に対するすべての単項レーンワイズ・ブール・テストのタイプで、m = v0. test(IS_FINITE)などの式で使用できます。
    w = v0. lanewise(NEG)などの式で使用可能な、すべてのレーンワイズ単項(1引数)演算子のタイプ。
    VectorShapeは、Vectorの特定の実装を選択します。
    VectorShuffleは、「ソース索引」と呼ばれる、順序付けされた不変の一連のint値を表します。各ソース索引は、互換性のあるVectorからソース・レーンを数値で選択します。
    「要素型」 (ETYPE)とshapeの同じ組合せのすべてのベクトルを管理するためのインタフェース。