gpt4 book ai didi

c - 我们可以在常规寄存器中存储浮点吗?

转载 作者:太空宇宙 更新时间:2023-11-04 00:28:06 26 4
gpt4 key购买 nike

据我所知,浮点存储在XMM寄存器中,而不是像eax这样的通用寄存器中,所以我做了一个实验:

float a = 5;

在这种情况下, a作为 1084227584存储在 XMM寄存器中。
以下是程序集版本:
.text
.global _start
.LCO:
.long 1084227584
_start:
mov .LCO, %eax
movss .LCO, %xmm0

执行上述程序集并使用 gdb对其进行调试表明, eax中的值将为 1084227584,而 ymm0中的值为 5
以下是我的问题:
1. XMM寄存器有什么特别之处除了SIMD指令之外,它们是存储浮点的唯一寄存器类型吗?
为什么我不能在常规寄存器中设置相同的位?
2. floatdouble值是否始终存储为浮点?
我们不能把它们作为 fixed point存储在C或汇编中吗?

最佳答案

然而,ymm0中的值是5。
ymm0中的位模式是1084227584这个数字的浮点解释是5.0
但您可以print /x $xmm0.v4_int32查看xmm0中位的十六进制表示。
XMM寄存器有什么特别之处除了SIMD指令之外,它们是存储浮点的唯一寄存器类型吗?
不,在asm中,一切都是字节。
有些编译器将使用整数寄存器将浮点或双精度运算从一个内存位置复制到另一个内存位置(如果不对其进行任何计算)(整数指令通常较小)例如,clang将执行以下操作:https://godbolt.org/z/76EWMY

void copy(float *d, float *s) {   *d = *s; }

# clang8.0 -O3 targeting x86-64 System V
copy: # @copy
mov eax, dword ptr [rsi]
mov dword ptr [rdi], eax
ret

XMM/YMM/ZMM寄存器是特殊的,因为它们是FP ALU指令存在的唯一寄存器(忽略X87,它仅用于X8664中的80位 long double)。
addsd xmm0, xmm1(add scalar double)没有整数寄存器的等效项。
通常FP和integer数据不太混合,因此提供一整套独立的体系结构寄存器可以为寄存器中的更多数据提供更多空间(给定相同的指令编码约束,可以选择16个FP+16个GP整数与16个统一寄存器,而不是32个统一寄存器)。
另外,独立寄存器文件的一个主要微体系结构优点是,它可以物理上接近FP alu,而整数寄存器文件可以物理上接近整数alu。有关更多信息,请参见 Is there any architecture that uses the same register space for scalar integer and floating point operations?
floatdouble值是否始终存储为浮点?我们永远不能把它们作为固定点存储在C或汇编中吗?
x86编译器使用 float=IEEE754 binary32 https://en.wikipedia.org/wiki/Single-precision_floating-point_format(和 double=IEEE754二进制64)。这被指定为ABI的一部分。
在内部,仿佛规则允许编译器做它想做的任何事情,只要最终结果相同(或者使用 -ffast-math,假装FP math是关联的,并假设NaN/Inf是不可能的。)
编译器不能为某些 float随机选择其他单独编译的函数可能看到的不同对象表示。
对于其他函数看不到的局部变量,可能很少有“人工编译器”(手工编写asm来实现C)可以证明定点是安全的或者更可能的是, float值是精确的整数,小到 double无法舍入它们,因此您的不动点可能退化为整数(除了最后一步)。
但是,如果不能够进行不断的传播和优化,就很难对可能的值了解这么多这就是为什么我说必须有人参与进来,来证明编译器不知道要寻找的东西。
我认为从理论上讲,您可以有一个使用定点 floatdouble的C实现。ISO C对 floatdouble实际上是什么几乎没有限制。
但是 limits.h constants like FLT_RADIX and DBL_MAX_EXP的交互对于固定点格式来说可能没有意义,固定点格式在每个可表示的值之间具有恒定的距离,而不是在接近0时更接近,在大量情况下则相距更远。(0.5ulp的舍入误差是相对于幅度的,而不是绝对的。)
不过,如果“尾数”和指数限制与您对 DBL_MINDBL_MAX的预期不符,大多数程序实际上不会执行可能会中断的操作。
另一个有趣的可能性是基于Posit格式(类似于传统的浮点,但具有可变长度的指数编码)生成 floatdouble https://www.johndcook.com/blog/2018/04/11/anatomy-of-a-posit-number/ https://posithub.org/index)。
现代硬件,特别是Intel cpu,对IEEE float/double有很好的支持,所以定点通常不是一个好的选择。不过,对于16位定点,有一些很好的SIMD指令,比如高半乘法,甚至 pmulhrsw都是定点舍入。
但是一般的32位整数乘法的吞吐量比压缩乘法要差(因为为float/double优化的SIMD alu每32位向量元素只需要24x24位有效位乘法器。现代Intel CPU在FMA执行单元上运行整数乘法和移位,每时钟吞吐量为2 UOP。)

关于c - 我们可以在常规寄存器中存储浮点吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55623357/

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