LLVM IR:有效地对向量求和
我正在编写一个生成LLVM IR指令的编译器。我正在广泛研究向量 我希望能够对向量中的所有元素求和。现在,我只是单独提取每个元素并手动将它们相加,但我突然想到,这正是硬件应该能够帮助解决的问题(因为这听起来像是一个非常常见的操作)。但这似乎没有内在的原因LLVM IR:有效地对向量求和,llvm,llvm-ir,llvm-3.2,Llvm,Llvm Ir,Llvm 3.2,我正在编写一个生成LLVM IR指令的编译器。我正在广泛研究向量 我希望能够对向量中的所有元素求和。现在,我只是单独提取每个元素并手动将它们相加,但我突然想到,这正是硬件应该能够帮助解决的问题(因为这听起来像是一个非常常见的操作)。但这似乎没有内在的原因 最好的方法是什么?我使用的是LLVM 3.2。首先,即使不使用内部函数,也可以生成log(n)向量加法(n为向量长度),而不是n标量加法,下面是向量大小为8的示例: define i32 @sum(<8 x i32> %a) {
最好的方法是什么?我使用的是LLVM 3.2。首先,即使不使用内部函数,也可以生成
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
}
define i32@sum(%a){
%v1=shufflevector%a,未定义,
%v2=shufflevector%a,未定义,
%sum1=添加%v1,%v2
%v3=shufflevector%sum1,未定义,
%v4=shufflevector%sum1,未定义,
%sum2=添加%v3,%v4
%v5=提取元素%sum2,i32 0
%v6=提取元素%sum2,i32 1
%sum3=添加i32%v5,%v6
ret i32%sum3
}
如果您的目标支持这些向量加法,则很可能会降低上述内容以使用这些指令,从而提高您的性能
关于内部函数,没有独立于目标的内部函数来处理这个问题。但是,如果您正在编译到x86,您确实可以访问hadd
instrinsic(例如llvm.x86.int\u x86\u ssse3\u phadd\u sw\u 128
以将两个
向量添加到一起)。您仍然需要执行与上述类似的操作,只能替换add
指令
有关这方面的更多信息,您可以搜索“水平和”或“水平向量和”;例如,对于x86上的水平和,以下是一些相关的stackoverflow问题: