我知道C和C++标准留下了语言实现的许多方面 - 仅仅因为如果存在具有其他特征的体系结构,那么为它编写符合标准的编译器是非常困难或不可能的.
我知道40年前任何电脑都有自己独特的规格.但是,我不知道今天使用的任何架构:
CHAR_BIT != 8
signed
不是两个补充(我听说Java有这个问题).
浮点不符合IEEE 754(编辑:我的意思是"不是IEEE 754二进制编码").
我问的原因是我经常向人们解释C++不强制要求任何其他低级方面如固定大小的类型†.这很好,因为与其他语言不同,它使你的代码在正确使用时可以移植(编辑:因为它可以移植到更多架构而不需要模拟机器的低级方面,例如符号+幅度架构上的二进制补码算法) .但我感到很难过,我自己也无法指出任何特定的架构.
所以问题是:哪些架构具有上述属性?
† uint*_t
s是可选的.
看看这一个
Unisys ClearPath Dorado服务器
为尚未迁移所有Univac软件的人提供向后兼容性.
关键点:
36位字
CHAR_BIT == 9
一个补充
72位非IEEE浮点
代码和数据的单独地址空间
文字处理
没有专用的堆栈指针
不知道他们是否提供了C++编译器,但他们可以.
现在,他们的C手册的最新版本的链接浮出水面:
Unisys C编译器编程参考手册
第4.5节有一个包含9,18,36和72位的数据类型表.
你的假设都不适用于大型机.对于初学者,我不知道使用IEEE 754的大型机:IBM使用基本16浮点,两个Unisys大型机都使用基数8.Unisys机器在许多其他方面有点特别:Bo提到了2200架构,但MPS架构甚至更奇怪:48位标记的字.(单词是否为指针取决于单词中的位.)并且数值表示被设计为浮点和积分算法之间没有真正的区别:浮点数为8; 它不需要归一化,并且与我见过的每个其他浮点不同,它将小数放在尾数的右边而不是左边,并使用带符号的指数(除了尾数).结果是整数浮点值具有(或可以具有)与带符号幅度整数完全相同的位表示.并且没有浮点算术指令:如果两个值的指数都为0,则指令执行积分算术,否则执行浮点运算.(体系结构中标记哲学的延续.)这意味着虽然int
可能占用48位,但其中8位必须为0,否则该值不会被视为整数.
在浮点实现中,完全符合IEEE 754标准.在这方面削弱规范可以进行大量优化.
例如,子规范支持x87和SSE之间的差异.
融合在源代码中单独的乘法和加法的优化也稍微改变了结果,但在某些体系结构上是很好的优化.
或者在x86严格的IEEE兼容性上可能需要设置某些标志或浮点寄存器和普通内存之间的额外传输以强制它使用指定的浮点类型而不是其内部80位浮点数.
有些平台根本没有硬件浮动,因此需要在软件中模拟它们.并且IEEE 754的一些要求在软件中实现可能是昂贵的.特别是舍入规则可能是个问题.
我的结论是,如果您不总是希望保证严格的IEEE合规性,那么您不需要异国情调的架构.因此,很少有编程语言可以保证严格的IEEE合规性.
我发现这个链接列出了一些系统,其中CHAR_BIT != 8
.他们包括
一些TI DSP有
CHAR_BIT == 16
BlueCore-5芯片(Cambridge Silicon Radio的蓝牙芯片)有
CHAR_BIT == 16
.
当然,Stack Overflow还有一个问题:除了8位字符之外,哪些平台还有其他东西
对于非二进制补码系统,有一个关于 comp.lang.c ++.moderated的有趣读物.总结:有些平台具有补码或符号和幅度表示.
我很确定VAX系统仍在使用中.它们不支持IEEE浮点数; 他们使用自己的格式.Alpha支持VAX和IEEE浮点格式.
像T90这样的Cray矢量机也有自己的浮点格式,尽管较新的Cray系统使用IEEE.(我使用的T90在几年前退役了;我不知道是否有任何仍在使用中.)
T90还有一些有趣的表示指针和整数.本地地址只能指向64位字.C和C++编译器有CHAR_BIT == 8(必要因为它运行Unicos,一种Unix的风格,并且必须与其他系统互操作),但是本机地址只能指向64位字.所有字节级操作都由编译器合成,并且在字的高3位中存储void*
或char*
存储字节偏移.我认为一些整数类型有填充位.
IBM大型机是另一个例子.
另一方面,这些特定系统不一定排除对语言标准的改变.Cray没有表现出将C编译器升级到C99的特别兴趣; 大概是同样适用于C++编译器的东西.这可能是合理的收紧不填充比特托管实现,比如要求CHAR_BIT == 8,IEEE格式浮点如果不是全部语义,二进制补码的要求有符号整数.旧系统可以继续支持早期的语言标准(当C99出现时C90没有死亡),并且对于诸如DSP的独立实现(嵌入式系统),要求可能更宽松.
另一方面,未来的系统可能有充分的理由去做今天被认为是异国情调的事情.
根据gcc源代码:
CHAR_BIT
是16
对位1750A,dsp16xx架构.
CHAR_BIT
是dsp56k架构的24
位.是c4x架构的位.
CHAR_BIT
32
你可以通过以下方式轻松找到更多:
find $GCC_SOURCE_TREE -type f | xargs grep "#define CHAR_TYPE_SIZE"
要么
find $GCC_SOURCE_TREE -type f | xargs grep "#define BITS_PER_UNIT"
如果CHAR_TYPE_SIZE
适当定义.
如果目标体系结构不支持浮点指令,gcc可能会生成软件回退,默认情况下不符合标准.-funsafe-math-optimizations
除此之外,还可以使用特殊选项(例如,女巫也禁用保留零的符号).
直到最近,IEEE 754二进制表示在GPU上并不常见,请参阅GPU浮点偏执狂.
编辑:评论中提出的问题是GPU浮点是否与通常的计算机编程相关,与图形无关.当然好!今天工业计算的大多数高性能产品都是在GPU上完成的; 该列表包括AI,数据挖掘,神经网络,物理模拟,天气预报等等.评论中的一个链接显示了为什么:GPU的一个数量级的浮点优势.
我想补充的另一件事是,与OP问题更相关:10-15年前人们做什么,当GPU浮点数不是IEEE时,以及没有像今天的OpenCL或CUDA这样的GPU来编程GPU?信不信由你,早期的GPU计算先驱设法在没有API的情况下对GPU进行编程!我在公司遇到了其中一个.这就是他所做的:他将计算所需的数据编码为图像,其中像素表示他正在处理的值,然后使用OpenGL执行他需要的操作(例如"高斯模糊"来表示具有正态分布的卷积等),并将得到的图像解码回结果数组.这仍然比使用CPU更快!
这样的事情促使NVidia最终使其内部数据二进制与IEEE兼容并引入面向计算而不是图像处理的API.