如何将vector中的值相互添加

时间:2015-06-08 21:22:24

标签: x86 sse simd gas att

在我的代码中我解决了整数

y=x^2-4x+6

我使用SSE - 它允许我一次操作4个值。我制作的程序解决了这个积分,从0到5的值分为5个4元素向量n1,n2,n3,n4。

.data
n1: .float 0.3125,0.625,0.9375,1.25
n2: .float 1.5625,1.875,2.1875,2.5
n3: .float 2.8125,3.12500,3.4375,3.75
n4: .float 4.0625,4.37500,4.6875,5
szostka: .float 6,6,6,6
czworka: .float 4,4,4,4
.text
.global main
main:  
        movups (n1),%xmm0

        mulps %xmm0,%xmm0
        movups (szostka),%xmm2
        addps %xmm2,%xmm0
        movups (n1),%xmm1
        movups (czworka),%xmm2
        mulps %xmm2,%xmm1
        subps %xmm1,%xmm0
        movups %xmm0,%xmm7

        movups (n2),%xmm0

        mulps %xmm0,%xmm0
        movups (szostka),%xmm2
        addps %xmm2,%xmm0
        movups (n1),%xmm1
        movups (czworka),%xmm2
        mulps %xmm2,%xmm1
        subps %xmm1,%xmm0
        movups %xmm0,%xmm6

        movups (n3),%xmm0

        mulps %xmm0,%xmm0
        movups (szostka),%xmm2
        addps %xmm2,%xmm0
        movups (n1),%xmm1
        movups (czworka),%xmm2
        mulps %xmm2,%xmm1
        subps %xmm1,%xmm0
        movups %xmm0,%xmm5

        movups (n4),%xmm0

        mulps %xmm0,%xmm0
        movups (szostka),%xmm2
        addps %xmm2,%xmm0
        movups (n1),%xmm1
        movups (czworka),%xmm2
        mulps %xmm2,%xmm1
        subps %xmm1,%xmm0
        movups %xmm0,%xmm4

        mov $1,%eax
        mov $0,%ebx
        int $0x80 

最后,我在寄存器xmm7,xmm6,xmm5,xmm4中有4个向量。为了解决积分问题,我需要相互添加向量(这很容易),然后将向量中的值也相互添加 我该怎么做?

1 个答案:

答案 0 :(得分:1)

正如Paul R在评论中所说,你可以在一个向量中使用haddps作为横向操作。

您的代码看起来效率低下。如果你要完全展开,而不是使用循环和累加器,你可以在每个副本的第一个位置使用不同的寄存器,而不是在每个块的末尾都有movups %xmm0,%xmmX

此外,请在迭代中将(szostka)(czworka)保留在寄存器中。不要每次都重新加载它们。同样,将movups (n1),%xmm1替换为movups %xmm0, %xmm1(在你%xmm0之前)。在IvyBridge及更高版本中,寄存器重命名阶段处理reg-reg移动,它们以零延迟发生。

如果您确实需要每次都加载(szostka),最好将addps与内存操作数一起使用,而不是单独移动和添加。微融合可以将该操作保持为单一的uop。

查看http://agner.org/optimize/了解如何优化装配的文档。您可能会发现使用内在函数更有用,让编译器处理寄存器分配等小细节,而不是直接写入asm。