当前位置:  开发笔记 > 编程语言 > 正文

标准委员会关心的异域架构

如何解决《标准委员会关心的异域架构》经验,为你挑选了7个好方法。

我知道C和C++标准留下了语言实现的许多方面 - 仅仅因为如果存在具有其他特征的体系结构,那么为它编写符合标准的编译器是非常困难或不可能的.

我知道40年前任何电脑都有自己独特的规格.但是,我不知道今天使用的任何架构:

CHAR_BIT != 8

signed 不是两个补充(我听说Java有这个问题).

浮点不符合IEEE 754(编辑:我的意思是"不是IEEE 754二进制编码").

我问的原因是我经常向人们解释C++不强制要求任何其他低级方面如固定大小的类型.这很好,因为与其他语言不同,它使你的代码在正确使用时可以移植(编辑:因为它可以移植到更多架构而不需要模拟机器的低级方面,例如符号+幅度架构上的二进制补码算法) .但我感到很难过,我自己也无法指出任何特定的架构.

所以问题是:哪些架构具有上述属性?

uint*_ts是可选的.



1> Bo Persson..:

看看这一个

Unisys ClearPath Dorado服务器

为尚未迁移所有Univac软件的人提供向后兼容性.

关键点:

36位字

CHAR_BIT == 9

一个补充

72位非IEEE浮点

代码和数据的单独地址空间

文字处理

没有专用的堆栈指针

不知道他们是否提供了C++编译器,但他们可以.


现在,他们的C手册的最新版本的链接浮出水面:

Unisys C编译器编程参考手册

第4.5节有一个包含9,18,36和72位的数据类型表.

USC C编译器中数据类型的大小和范围


@ybungalobill:在旧的Win16编译器上,常规指针靠近指针并且只包含一个16位偏移量,所以`sizeof(int*)== 2`,但是远指针也有一个16位选择器,所以`sizeof(void)*)== 4`.
@Adam Rosenfield在MS/DOS 16位编译器上,你有不同的"模式",数据指针的大小不一定与函数指针相同.但至少在我使用的那些中,所有数据指针(包括`void*`)总是具有相同的大小.(当然,您无法将函数指针转换为`void*`,因为`void*`可能更小.但根据标准,您今天也不能这样做.)
我想无效*必须是在该架构中使用的地狱.
@ybungalobill - 我相信`char*`和`void*`必须是相同的大小,并且足够大以容纳任何其他指针.其余的由实施决定.
有或曾经是他们的C++编译器的在线手册.另外值得指出的是,这仅仅是Unisys的大型机架构之一:另一种是48位有符号幅度标记架构(为此我只发现了一个C语言手册,而不是C++的一个).关于其余部分:我不认为`sizeof(int*)!= sizeof(char*)`这里:两者都是36位.但是`char*`中的字节选择器位于高位,并且在`int*`中被忽略.(我使用过其他机器,其中`sizeof(char*)> sizeof(int*).)
@Bo Persson你真的在这台机器上编程了吗?我记得我在几年前下载的C++手册中读到的内容.我的记忆容易犯错,所以我很容易出错.但是从我在其他字处理机器上看到的情况来看:如果该字包含的位数多于寻址所需的位数(并且这些机器的日期是24位大部分足以用于寻址的时期),则附加的字节选择器被放入高阶位,而不是单独的单词.
@Calmarius历史原因.
`sizeof(char*)!= sizeof(int*)`甚至标准?
@James - 很久以前.我的大学有一台Univac 1100,我在那里学习了建筑.C++当时不可用(根本没有!)所以我不确定它会是什么样子.

2> James Kanze..:

你的假设都不适用于大型机.对于初学者,我不知道使用IEEE 754的大型机:IBM使用基本16浮点,两个Unisys大型机都使用基数8.Unisys机器在许多其他方面有点特别:Bo提到了2200架构,但MPS架构甚至更奇怪:48位标记的字.(单词是否为指针取决于单词中的位.)并且数值表示被设计为浮点和积分算法之间没有真正的区别:浮点数为8; 它不需要归一化,并且与我见过的每个其他浮点不同,它将小数放在尾数的右边而不是左边,并使用带符号的指数(除了尾数).结果是整数浮点值具有(或可以具有)与带符号幅度整数完全相同的位表示.并且没有浮点算术指令:如果两个值的指数都为0,则指令执行积分算术,否则执行浮点运算.(体系结构中标记哲学的延续.)这意味着虽然int可能占用48位,但其中8位必须为0,否则该值不会被视为整数.


IBM大型机(z/Architecture)确实支持IEE754浮点.
@Nikita - 他们*现在*.最初它是支持Java的(昂贵的)附加组件.

3> CodesInChaos..:

在浮点实现中,完全符合IEEE 754标准.在这方面削弱规范可以进行大量优化.

例如,子规范支持x87和SSE之间的差异.

融合在源代码中单独的乘法和加法的优化也稍微改变了结果,但在某些体系结构上是很好的优化.

或者在x86严格的IEEE兼容性上可能需要设置某些标志或浮点寄存器和普通内存之间的额外传输以强制它使用指定的浮点类型而不是其内部80位浮点数.

有些平台根本没有硬件浮动,因此需要在软件中模拟它们.并且IEEE 754的一些要求在软件中实现可能是昂贵的.特别是舍入规则可能是个问题.

我的结论是,如果您不总是希望保证严格的IEEE合规性,那么您不需要异国情调的架构.因此,很少有编程语言可以保证严格的IEEE合规性.


另一个"异国情调"的硬件集是IBM大型机,浮点格式早于IEEE标准.与Java不同,C++仍然可以使用现有的硬件.
GPU不完全支持IEEE 754.
缺乏对IEEE 754的严格遵守对某些人来说是一件麻烦事,但我认为这并不是OP真正关心的问题的范围.
@Matthieu由于这也标记为"C",我应该提到一个C分析器,它可以告诉你浮点数程序可能采用的所有值,80位浮点寄存器在C编译器的奇思妙想中溢出到内存.http://blog.frama-c.com/index.php?post/2011/03/03/cosine-for-real
@MatthieuM.:太糟糕了ISO/ANSI不允许可变参数为浮点和整数参数指定最小/最大值; 如果他们有,那么80位的"long double"可能是一个有用且长寿命的类型,因为它的一个真正的问题是它与`printf`一起工作很糟糕.事实上,扩展的double存储前导1明确地加速了非FPU系统的计算,并且还消除了在除了与其他类型的转换之外的任何上下文中对非正规的特殊处理的需要.太糟糕了C的'printf`搞砸了一切.

4> dcn..:

我发现这个链接列出了一些系统,其中CHAR_BIT != 8.他们包括

一些TI DSP有 CHAR_BIT == 16

BlueCore-5芯片(Cambridge Silicon Radio的蓝牙芯片)有CHAR_BIT == 16.

当然,Stack Overflow还有一个问题:除了8位字符之外,哪些平台还有其他东西

对于非二进制补码系统,有一个关于 comp.lang.c ++.moderated的有趣读物.总结:有些平台具有补码或符号和幅度表示.


ADI公司的32位SHARC DSP具有"CHAR_BIT = 32",而TMS32F28xx的德州仪器DSP具有"CHAR_BIT = 16".用于PDP-10的GCC 3.2具有"CHAR_BIT = 9".我认为,S/360也可能有一个非8位字符.

5> Keith Thomps..:

我很确定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的独立实现(嵌入式系统),要求可能更宽松.

另一方面,未来的系统可能有充分的理由去做今天被认为是异国情调的事情.


最后关于过于严格的标准如何阻止创新的好点.当我们得到具有三态的量子(或有机)计算机时,"无符号"积分类型的模运算要求将是一个主要的痛苦,而有符号算术将是正常的.
@LưuVĩnhPhúc:正是这样,硬件操作以模3 \ * \ * n执行,要提供C ++无符号类型,其操作以模2 \ * \ * n定义将是困难的。

6> ivaigult..:

CHAR_BITS

根据gcc源代码:

CHAR_BIT16对位1750A,dsp16xx架构.
CHAR_BITdsp56k架构的24位.是c4x架构的位.
CHAR_BIT32

你可以通过以下方式轻松找到更多:

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适当定义.

符合IEEE 754标准

如果目标体系结构不支持浮点指令,gcc可能会生成软件回退,默认情况下不符合标准.-funsafe-math-optimizations除此之外,还可以使用特殊选项(例如,女巫也禁用保留零的符号).


赞成仅指示OP查看流行编译器的源代码;在这种情况下,这就是RFTM的定义,因此应该成为人们关注的首要内容。

7> Michael..:

直到最近,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.


@ybungalobill:几个答案.首先,[CUDA支持C,C++和Fortran](http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#axzz4N5KlOXmv).请参阅相同链接,了解2048线程GPU相对于典型8线程CPU的巨大性能优势.其次,只支持这些语言的子集(尽管很大),包括在CUDA 5.0之前缺乏对CUDA编程模型递归(称为"动态并行")的适当支持.第三,递归通常可以用循环代替,这对于多线程性能来说无论如何都是必需的.
推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有