web-dev-qa-db-ja.com

「ベクトル化」とは何ですか?

数回、matlab、fortranでこの用語に遭遇しました...他の...ここで、ベクトル化とは何ですか、たとえば「ループがベクトル化される」とはどういう意味ですか?

145
Thomas Geritzma

多くのCPUには、2つ、4つ、またはそれ以上のデータに同じ操作を同時に適用する「ベクター」または「SIMD」命令セットがあります。最新のx86チップにはSSE命令があり、多くのPPCチップには「Altivec」命令があり、一部のARMチップでもNEONと呼ばれるベクトル命令セットがあります。

「ベクトル化」(簡略化)は、ループの書き換えプロセスで、配列の1つの要素をN回処理する代わりに、配列の4つの要素をN/4回同時に処理します。

(最近のハードウェアが直接サポートする可能性が最も高いものであるため、4を選択しました。「ベクトル化」という用語は、ループを完全に抽象化し、要素ではなく配列で操作することを説明する高レベルのソフトウェア変換を表すためにも使用されますそれらを構成する)


ベクトル化とループ展開の違い: 2つの配列の要素を追加し、結果を3番目の配列に保存する次の非常に単純なループを考えてください。

for (int i=0; i<16; ++i)
    C[i] = A[i] + B[i];

このループを展開すると、次のようなものに変換されます。

for (int i=0; i<16; i+=4) {
    C[i]   = A[i]   + B[i];
    C[i+1] = A[i+1] + B[i+1];
    C[i+2] = A[i+2] + B[i+2];
    C[i+3] = A[i+3] + B[i+3];
}

一方、ベクトル化すると、次のようなものが生成されます。

for (int i=0; i<16; i+=4)
    addFourThingsAtOnceAndStoreResult(&C[i], &A[i], &B[i]);

ここで、「addFourThingsAtOnceAndStoreResult」は、コンパイラーがベクトル命令を指定するために使用する組み込み関数のプレースホルダーです。一部のコンパイラーは、このような非常に単純なループをauto vectorizeできることに注意してください。これは、多くの場合、コンパイルオプションで有効にできます。より複雑なアルゴリズムでも、優れたベクターコードを生成するには、プログラマーの支援が必要です。

174
Stephen Canon

ベクトル化は、スカラープログラムをベクトルプログラムに変換するための用語です。ベクトル化されたプログラムは単一の命令から複数の操作を実行できますが、スカラーは一度にオペランドのペアに対してのみ操作できます。

wikipedia から:

スカラーアプローチ:

for (i = 0; i < 1024; i++)
{
   C[i] = A[i]*B[i];
}

ベクトル化されたアプローチ:

for (i = 0; i < 1024; i+=4)
{
   C[i:i+3] = A[i:i+3]*B[i:i+3];
}
30
Anders

これは、1つのステップで数値のリスト(つまり「ベクトル」)に対して単一の数学演算を実行する機能を指します。 Fortranでよく見ます。これは、ベクトル化された算術が最初に現れたスーパーコンピューティングに関連する科学計算に関連しているためです。現在、ほとんどすべてのデスクトップCPUは、IntelのSSEなどのテクノロジーを通じて、何らかの形のベクトル化された演算を提供しています。 GPUは、ベクトル化された演算の形式も提供します。

10
Warren Young

ベクトル化は、大量のデータを効率的に処理する必要がある科学計算で大いに使用されます。

実際のプログラミングアプリケーションでは、それがNUMPYで使用されていることを知っています(他にはわかりません)。

Numpy(Pythonの科学計算用パッケージ)、vectorizationを使用して、n次元配列の高速な操作を行います。これは、組み込みのpython options配列の処理。

大量の説明がありますが、ここは何ですか[〜#〜] vectorization [〜#〜] IS DEFINED AS IN IN NUMPY DOCUMENTATION PAGE =

ベクトル化は、コードに明示的なループ、インデックス付けなどが存在しないことを示します。これらのことは、もちろん、最適化され、プリコンパイルされたCコードで「舞台裏」で行われます。ベクトル化されたコードには、次のような多くの利点があります。

  1. ベクトル化されたコードはより簡潔で読みやすい

  2. 一般に、コード行が少ないということは、バグが少ないことを意味します

  3. コードは、標準の数学表記法によりよく似ています(通常、数学的な構造を正しくコーディングするのが簡単になります)

  4. ベクトル化により、より「Python的な」コードが生成されます。ベクトル化を行わないと、コードのループが効率的でなく読みにくくなります。

6
bad programmer

ベクトル化とは、簡単に言うと、プロセッサでSIMD命令を利用できるようにアルゴリズムを最適化することを意味します。

AVX、AVX2、AVX512は、1つの命令で複数のデータに対して同じ操作を実行する命令セット(Intel)です。例えばAVX512は、一度に16個の整数値(4バイト)を操作できることを意味します。つまり、16個の整数のベクトルがあり、各整数でその値を2倍にしてから10を足したい場合です。値を汎用レジスタ[a、b、c]に16回ロードして同じ操作を実行するか、16個すべての値をSIMDレジスタ[xmm、ymm]にロードして同じ操作を1回実行することができます。これにより、ベクターデータの計算を高速化できます。

ベクトル化では、データを再モデリングしてSIMD操作を実行し、プログラムを高速化することにより、これを活用します。

ベクトル化の問題のみが条件の処理です。条件は実行の流れを分岐させるためです。これはマスキングによって処理できます。条件を算術演算にモデル化する。例えば。値が100を超える場合、値に10を加算します。どちらでも可能です。

if(x[i] > 100) x[i] += 10; // this will branch execution flow.

または、条件ベクトルcを作成する算術演算に条件をモデル化できます。

c[i] = x[i] > 100; // storing the condition on masking vector
x[i] = x[i] + (c[i] & 10) // using mask

ただし、これは非常に簡単な例です。したがって、cはその値に基づいてバイナリ演算を実行するために使用するマスキングベクトルです。これにより、実行フローの分岐が回避され、ベクトル化が可能になります。

ベクトル化は並列化と同じくらい重要です。したがって、可能な限りそれを利用する必要があります。現代のすべてのプロセッサには、重い計算ワークロード用のSIMD命令があります。ベクトル化を使用してこれらのSIMD命令を使用するようにコードを最適化できます。これは、最新のプロセッサーで利用可能な複数のコアで実行するようにコードを並列化することに似ています。

プラグマを使用してコードをベクトル化できるOpenMPについて言及したいと思います。良い出発点だと思います。 OpenACCについても同じことが言えます。

2
Market Queue