【问题标题】:How to add values from vector to each other如何将向量中的值相互添加
【发布时间】:2015-06-08 21:22:23
【问题描述】:

在我的代码中我解决积分问题

y=x^2-4x+6

我使用了 SSE - 它允许我一次对 4 个值进行操作。我编写了一个程序,用从 0 到 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 个向量。为了解决积分问题,我需要将向量相互添加(这很容易),然后将向量中的值也相互添加。
我该怎么做?

【问题讨论】:

  • 假设你想水平添加元素,你可以使用haddps。您需要调用它两次才能将所有 4 个元素相加。
  • 请记住,haddps 需要 SSE3 支持。
  • 那么我还能做些什么吗?
  • 你是说你的 CPU 没有 SSE3,即它已经 > 10 岁了吗?
  • 不!老实说,我只是要开始阅读有关此的内容。

标签: x86 sse simd gnu-assembler att


【解决方案1】:

正如 Paul R 在评论中所说,您可以在最后将 haddps 用于向量内的水平操作。

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

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

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

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

【讨论】:

  • This question 为您解答。
  • @Zboson:感谢您的 ping。我离开了几天去蒙克顿看望我的兄弟,看他参加的晚宴剧场表演。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-08
  • 2021-02-18
  • 2018-04-02
  • 2020-07-12
相关资源
最近更新 更多