在我的代码中我解决了整数
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个向量。为了解决积分问题,我需要相互添加向量(这很容易),然后将向量中的值也相互添加 我该怎么做?
答案 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。