有人告诉我:
在x86-64下,FP算法是通过SSE完成的,因此long double是64位。
但是在x86-64 ABI中它表示:
C type | sizeof | alignment | AMD64 Architecture
long double | 16 | 16 | 80-bit extended (IEEE-754)
参见:amd64-abi.pdf
和gcc说sizeof(long double)
是16并给出FLT_DBL
= 1.79769e+308
和FLT_LDBL = 1.18973e+4932
所以我很困惑,long double
64位怎么样?我认为这是一个80位的表示形式。
在x86-64下,FP算法是通过SSE完成的,因此long double是64位。
这就是 通常发生 X86-64(其中的SSE指令的存在保证)之下,但该计划仍然是免费使用的x87,将通过在您使用编译器可以求助于long double
。
您可以通过g++
在Linux上编译如下程序来确认这一点:
#include <iostream>
#include <cstdlib>
#include <ctime>
int main()
{
std::srand(std::time(NULL));
float f1=rand(), f2=rand();
double d1=rand(), d2=rand();
long double l1=rand(), l2=rand();
std::cout<<f1*f2<<" "<<d1*d2<<" "<<l1*l2<<std::endl;
return 0;
}
在装配输出,我找到mulsd xmm1, xmm0
了double
产品和mulss xmm0, xmm2
对float
产品(包括SSE指令),但fmulp st(1), st
(的x87指令)的long double
产品。
因此,可以肯定的是,编译器会在可能的情况下使用SSE,但仍允许通过旧的x87指令集进行80位精度的计算。
请注意,这是特定于编译器的-一些编译器(例如VC ++)始终忽略80位精度类型,而只是将其long double
视为的同义词double
。
另一方面,由于x86-64 System V ABI(在Linux上采用)的要求long double
是80位,所以编译器使用该类型的所有可用精度执行计算的唯一方法是使用x87指令。
这是我的测试代码: 这是测试结果: 在x64 GNU/Linux上使用GCC 10.1.0,无论是使用-O2优化还是未优化,总是比快一点。 和都明显快于;已成为最慢的类型。 这是怎么发生的?
我认为2补码的全部意义在于可以以相同的方式实现有符号和无符号数字的操作。维基百科甚至特别将乘法列为受益的操作之一。那么为什么x86对每个都有单独的说明,和?x86-64仍然如此吗?
本文向大家介绍在i386和x86-64上UNIX和Linux系统调用的调用约定是什么,包括了在i386和x86-64上UNIX和Linux系统调用的调用约定是什么的使用技巧和注意事项,需要的朋友参考一下 系统调用是应用程序和Linux内核之间的基本接口。当Unix / Linux程序执行文件I / O,网络数据传输或调用某个与低级指令直接或间接交互的进程时,就会涉及系统调用。进行这些调用通常涉及使
问题内容: 我正在尝试使用syscall 在Linux中分配一些内存。这是我尝试过的: 事情是按照linux调用约定,我希望返回值在寄存器中(指向已分配内存的指针)。我在gdb中运行了此文件,并在进行了syscall 后注意到以下寄存器内容 在系统调用之前 系统调用后 在这种情况下,我不太了解寄存器中的值。哪个指针可以用作我分配给它的8个字节的开头的指针? 问题答案: 系统调用返回值始终位于中。请
我希望以尽可能短的汇编代码量反转字符串。 由于缺乏Unicorn支持,我只能使用SSSE3扩展或更少。我尝试访问ymm 即使SSSE3指令更简洁,用于128位XMM寄存器字节反转的16字节pshufb控制向量仍然占用16字节,使其更长。我对任何想法都持开放态度,但以下是我最好的尝试。 我需要32个字节或更少,越小越好。到目前为止,我得到的最好值是42,但我假设rdx(如果使用x86,则为ecx)内
我正在尝试创建一个愚蠢的自旋锁版本。浏览网页时,我在x86中遇到了一条名为“PAUSE”的汇编指令,该指令用于向处理器提示该CPU上当前正在运行自旋锁。英特尔手册和其他可用信息声明: 在大多数情况下,处理器使用此提示来避免内存顺序冲突,这大大提高了处理器性能。因此,建议在所有自旋等待循环中放置暂停指令。文档还提到“等待(一些延迟)”是指令的伪实现。 上段最后一行很直观,如果我抢锁不成功,我必须等一