当前位置: 首页 > 知识库问答 >
问题:

为什么gcc只使用_mm_set_ss添加这个movss指令?

祖波光
2023-03-14
#include <xmmintrin.h>

int ftrunc1(float f) {
    return _mm_cvttss_si32(_mm_set1_ps(f));
}

int ftrunc2(float f) {
    return _mm_cvttss_si32(_mm_set_ss(f));
}

对于任何输入,两者在行为上都是完全相同的。但是汇编器的输出是不同的:

ftrunc1:
    pushl   %ebp
    movl    %esp, %ebp
    cvttss2si   8(%ebp), %eax
    leave
    ret

ftrunc2:
    pushl   %ebp
    movl    %esp, %ebp
    movss   8(%ebp), %xmm0
    cvttss2si   %xmm0, %eax
    leave
    ret

也就是说,ftrunc2额外使用一条movss指令!

这正常吗?有关系吗?当您只需要设置底部元素时,_mm_set1_ps是否总是优于_mm_set_ss

共有1个答案

陶树
2023-03-14

_mm_set_ss直接映射到程序集指令(movss)。但是_mm_set1_ps没有。

从我在GCC、MSVC和ICC上看到的情况来看:

一对一映射到程序集指令的SSE内部通常被视为“原样”--一个黑盒。因此编译器只会对整个指令本身进行优化。但是它不会尝试进行任何需要对单个向量元素进行数据流/依赖关系分析的优化。

 类似资料:
  • 这与我对“流减少不兼容类型”的回答有关。我不知道为什么我的建议有效,霍尔格正确地敦促我这一点。但即使是他似乎也没有一个明确的解释为什么它能起作用。所以,让我们把它作为自己的问题来问: 以下代码不能在中编译(下面指向ideone的链接是,请参阅http://ideone.com/faq): 这样做是正确的:或者将这个流中的两个谓词结合在一起,就像写: IdeOne演示 尽管事实上我想尝试这一点,但我

  • 我发现这样的php代码: 我希望这个循环会执行4次,因为$I变成了对$的引用(对吗?)。然而,循环只执行一次,并输出: a=10,i=10 我不明白为什么它会这样工作。有什么想法吗?

  • 下面的代码基于@a.bertucci提供的一个示例,这里使用Android上的RxJava以固定的间隔在UI中绘制对象,其中我使用计时器压缩了一个可观察对象。当我通过调用processDelayedItems()触发订阅时,压缩的Observable中的代码[A]只执行一次,一个项目被发送到[B]。我原本希望代码[A]在触发后继续运行,并保持每1500毫秒发出一次项,但显然它在这里只运行一次。 >

  • 我在使用Google Benchmark优化函数时遇到了麻烦,在某些情况下,我的代码出乎意料地慢了下来。我开始对它进行实验,查看编译后的程序集,最终提出了一个展示该问题的最小测试用例。这是我提出的展示这种减速的组件: 此函数遵循GCC/Clang的x86-64调用约定,用于函数声明注意注释掉的指令。取消注释此指令显着提高了函数的性能。使用我的机器进行i7-8700K测试,Google基准测试显示,

  • 我正在使用凭据和预检请求实现CORS,我有点困惑为什么预检请求在Firefox 30中始终失败,但在Safari(7.0.2)和Chrome35中有效。我认为这个问题不同于“为什么经过身份验证的CORS请求的预检OPTIONS请求在Chrome而不是Firefox中有效?”因为我没有收到401,而是来自浏览器客户端的特定CORS消息: “跨源请求已阻止:同源策略不允许读取 http://myurl

  • 为什么在那里插入? 如果没有一个好的理由:我能用什么方法摆脱它吗? 如果您想使用以下示例:https://godbolt.org/z/74ycy63se

  • 谢谢你的帮助。Haskell看起来很有趣,但如果没有一个好教授的指导和指导,这是一门很难学的语言。我只是想自学这门语言。

  • 我试图插入二叉查找树使用递归,然后打印它预先使用这个特定的代码,但我只有根作为输出,为什么?这是因为每个时间栈(每次调用后)弹出从而删除新节点?这是一个java代码)