7

LLVM IR 命令を生成するコンパイラを作成しています。私はベクターを幅広く扱っています。

ベクトル内のすべての要素を合計できるようにしたいと考えています。現在、各要素を個別に抽出して手動で追加しているだけですが、これはまさにハードウェアが支援できるはずの種類のものだと思います (かなり一般的な操作のように思えます)。しかし、それを行うための本質的なものはないようです。

これを行う最善の方法は何ですか?LLVM 3.2 を使用しています。

4

1 に答える 1

5

まず、組み込み関数を使用しなくても、スカラー加算log(n)の代わりにベクトル加算(nはベクトルの長さ)を生成できますn。ベクトルサイズが8の例を次に示します。

define i32 @sum(<8 x i32> %a) {
  %v1 = shufflevector <8 x i32> %a, <8 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %v2 = shufflevector <8 x i32> %a, <8 x i32> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
  %sum1 = add <4 x i32> %v1, %v2
  %v3 = shufflevector <4 x i32> %sum1, <4 x i32> undef, <2 x i32> <i32 0, i32 1>
  %v4 = shufflevector <4 x i32> %sum1, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
  %sum2 = add <2 x i32> %v3, %v4
  %v5 = extractelement <2 x i32> %sum2, i32 0
  %v6 = extractelement <2 x i32> %sum2, i32 1
  %sum3 = add i32 %v5, %v6
  ret i32 %sum3
}

ターゲットがこれらのベクトルの追加をサポートしている場合は、これらの命令を使用するために上記が低くなる可能性が高く、パフォーマンスが向上します。

組み込み関数に関しては、これを処理するためのターゲットに依存しない組み込み関数はありません。ただし、x86にコンパイルする場合は、hadd本能にアクセスできます(たとえば、2つのベクトルを一緒llvm.x86.int_x86_ssse3_phadd_sw_128に追加する場合)。<4 x i32>上記と同様のことを行う必要がありますが、add置き換えることができるのは手順だけです。

これに関する詳細については、「水平和」または「水平ベクトル和」を検索できます。たとえば、x86の水平方向の合計に関連するスタックオーバーフローの質問を次に示します。

于 2013-02-07T08:34:14.423 に答える