質問

今、matlab、fortranでこの用語に出くわしました...他の...ここで、ベクトル化とは何ですか、たとえば、「ループはベクトル化されます」とはどういう意味ですか?

役に立ちましたか?

解決

多くのCPUには「ベクター」があります。または「SIMD」 2つ、4つ、またはそれ以上のデータに同じ操作を同時に適用する命令セット。最新の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]);

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

他のヒント

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

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];
}

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

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

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

Numpy(Pythonの科学計算用パッケージ)は、n次元配列の高速操作にベクトル化を使用します。これは、配列を処理するための組み込みのPythonオプションを使用すると一般に遅くなります。

説明はたくさんありますが、ここではベクトル化 NUMPY DOCUMENTATIONページのように定義されています

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

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

  2. コードの数が少ないほど、一般的にバグが少なくなります

  3. コードは、標準の数学表記にもっと似ています (通常、簡単に数学的なコードを記述しやすくします 構造体)

  4. ベクトル化により、より多くの&#8220; Pythonic&#8221;コード。なしで ベクトル化すると、コードが非効率的になり、 forループを読みにくい。

ベクトル化とは、簡単に言うと、プロセッサで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つの答えを参照してください。ベクトル化を行いたい理由は、これらの操作をスーパーコンピューターやマルチプロセッサーで簡単に実行でき、パフォーマンスが大幅に向上するからです。シングルプロセッサコンピューターでは、パフォーマンスは向上しません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top