gpt4 book ai didi

c++ - 为什么标准的 "abs"函数比我的快?

转载 作者:行者123 更新时间:2023-12-03 10:03:23 27 4
gpt4 key购买 nike

我想尝试制作自己的绝对值函数。我认为计算绝对值的最快方法是简单地屏蔽符号位(IEEE 754 中的最后一位)。我想将它的速度与标准速度进行比较 abs功能。这是我的实现:

// Union used for type punning
union float_uint_u
{
float f_val;
unsigned int ui_val;
};

// 'MASK' has all bits == 1 except the last one
constexpr unsigned int MASK = ~(1 << (sizeof(int) * 8 - 1));

float abs_bitwise(float value)
{
float_uint_u ret;
ret.f_val = value;
ret.ui_val &= MASK;

return ret.f_val;
}
作为记录,我知道这种类型的双关语不是标准的 C++。但是,这仅用于教育目的,根据文档, this is supported in GCC .
我认为这应该是计算绝对值的最快方法,因此它至少应该与标准实现一样快。但是,对随机值的 100000000 次迭代计时,我得到了以下结果:
Bitwise time: 5.47385 | STL time: 5.15662
Ratio: 1.06152
我的 abs函数慢了大约 6%。
组装输出
我用 -O2 编译优化和 -S选项(程序集输出)来帮助确定发生了什么。我已经提取了相关部分:
; 16(%rsp) is a value obtained from standard input
movss 16(%rsp), %xmm0
andps .LC5(%rip), %xmm0 ; .LC5 == 2147483647
movq %rbp, %rdi
cvtss2sd %xmm0, %xmm0

movl 16(%rsp), %eax
movq %rbp, %rdi
andl $2147483647, %eax
movd %eax, %xmm0
cvtss2sd %xmm0, %xmm0
观察
我不擅长汇编,但我注意到的主要事情是标准函数直接在 xmm0 上运行。登记。但是对于我的,它首先将值移动到 eax (出于某种原因),执行 and ,然后将其移动到 xmm0 .我假设额外的 mov是减速发生的地方。我还注意到,对于标准,它将位掩码存储在程序中的其他位置而不是立即数。不过,我猜这并不重要。这两个版本也使用不同的指令(例如 movlmovss )。
系统信息
这是在 Debian Linux(不稳定分支)上用 g++ 编译的。 g++ --version输出:
g++ (Debian 10.2.1-6) 10.2.1 20210110

如果这两个版本的代码都以相同的方式计算绝对值(通过 and ),为什么优化器不生成相同的代码?具体来说,为什么感觉需要包含一个额外的 mov什么时候优化我的实现?

最佳答案

我得到了一个有点不同的组件。根据 x86_64 Linux ABI,float参数通过 xmm0 传递.带标fabs ,按位 AND操作直接在这个寄存器上执行(Intel 语法):

andps xmm0, XMMWORD PTR .LC0[rip] # .LC0 contains 0x7FFFFFFF
ret
但是,在您的情况下,按位 AND对类型 unsigned int 的对象执行.因此,GCC 执行相同的操作,需要移动 xmm0eax第一的:
movd eax, xmm0
and eax, 2147483647
movd xmm0, eax
ret
现场演示: https://godbolt.org/z/xj8MMo
我还没有找到任何方法来强制 海合会要执行的优化器 AND直接上 xmm0仅使用纯 C/C++ 源代码。似乎高效的实现需要建立在汇编代码或 Intel 内在代码之上。
相关问题: How to perform a bitwise operation on floating point numbers .所有提出的解决方案基本上都会产生相同的结果。
我也尝试使用 copysign功能,但结果更糟。生成的机器代码然后包含 x87 指令。

无论如何, 很有趣。叮当优化器足够聪明,可以使所有 3 种情况下的程序集等效: https://godbolt.org/z/b6Khv5 .

关于c++ - 为什么标准的 "abs"函数比我的快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66023408/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com