2011年之前有一个类似的问题:Exotic architectures the standards committees care about
现在,我想问一个非常相似的问题,但这一次,我是从程序员的角度和C ++ 11的角度来看问题。
目前存在哪些硬件,它有一个C ++ 11编译器,可以被认为是异国情调?
我认为什么是异国情调?
所以我们在x86 / ARM世界中看到的不是标准的任何东西,我们在哪里:
注意:我想得到答案,其中存在符合C ++ 11标准的编译器用于硬件,而不是存在C ++编译器的地方,但不完全符合。
我问这个,因为很多时候,我得到的答案就像“你不能依赖它,它是实现定义的”,我想知道,实际上,在现实世界中,多少我可以依赖标准。举个例子:每当我写std::uint16_t
时,我可能会担心(因为此功能可选),在平台上,这种类型是不存在的。但是,是否存在这种类型不存在的实际平台?
答案 0 :(得分:6)
去寻找DSP内核,这是“异国情调”架构的最佳选择。
例如,Motorola / Freescale / NXP 56720有一个可从Tasking获得的C ++编译器,但在三个或更多总线上有24位内存。我认为设备上的堆栈模型(至少是较旧的56K设备)是硬件堆栈,并不适合C / C ++模型。
编辑:更多细节...
这头野兽的登记模型是奇怪的:
模数和步长寄存器不会映射到C / C ++中本质建模的任何东西,因此总会有一些奇怪的构造和#pragma
来帮助编译器支持循环缓冲区。
没有堆栈指针(没有push或pop指令)。有一个用于函数返回地址的硬件堆栈,但这只有16个深度调用。该软件必须管理溢出,并且本地变量不会存在于堆栈中。
因为没有堆栈,编译器会做一些奇怪的事情,比如静态调用树分析,并将局部变量放在重叠的内存池中。这意味着没有重入功能,只需要一个上下文,没有太多的怪异或严重的性能损失。
sizeof(int)
= sizeof(char)
= sizeof(short)
= 1
= 24位
这意味着没有字节访问(至少在旧的56002上,不确定56300)。我认为从24位整数数组中读取/写入特定字节大约需要24个周期。这个核心并不好,还有桶式移动,屏蔽和移动
当然不是所有的DSP内核都是这样的,但是它们通常与32/64位统一内存的标准有不同程度的“怪异”,并且由于内在的模数指针,它们的大小(char)= 1对GCC的期望和多个内存总线。
答案 1 :(得分:4)
有些计算机的寄存器位宽不同。
CDC Cyber系列使用6位表示常见字符,使用扩展12位表示非常见字符。
但是,为了符合C语言标准,编译器需要使用12位字符,因为6位不满足最小范围。
至于其他要求,您谈论的是宇宙的一小部分:自定义实现。某些平台可能有80位浮点。某些平台可能使用4位作为其最小可寻址单元。
大多数硬件组件制造商已对8位,16位,32位,64位或128位单元进行了标准化。要获得其他非标准单位,您可能需要增加现有的标准尺寸。标准化降低了集成电路的成本。
某些硬件组件(如数模转换器(DAC)和模数转换器(ADC))的位宽不能被8整除。例如,12位ADC非常常见。
让我们的谈话真正定制:可编程门阵列,例如FPGA中。基本上,您可以将器件编程为具有任意数量的位用于输入或输出或内部总线。
要点:
为了符合C或C ++标准,必须满足一组最低标准。编译器负责分配寄存器和内存以满足标准。如果字符是6位,则编译器必须使用两个6位单元才能满足字符的最小范围。
答案 2 :(得分:2)
当人们说某些内容是实现定义时,这并不仅适用于内存模型,基本变量大小等(即硬件实现),而是它可能依赖于一个特定的编译器实现(不同的编译器可能会以不同的方式处理某些事情而他们经常执行)和/或编译该程序的操作系统。因此,即使根据您的定义,绝大多数硬件可能都不具有异国情调,但仍然"您不能依赖它,它是实现定义的" ;)
示例:C ++标准规定long double
类型必须至少与常规double
一样大(即8个字节),但它<\ n < strong>实现定义,实际上,对于x64平台,g ++实现long double
为16字节长,最新的VC ++编译器最小化,而现在long double
只有8字节很久就像double
一样,但这可能会在将来发生变化 - 你永远不会知道它的实现定义,微软可以随时随地改变它,标准仍然可以坚持。
这不是您提出的问题的确切答案,但是回答了问题的最后几段(&#34;我可以依赖标准多少?&#34;)并且显然可能让你回顾一下你对这个问题的看法。此外,评论时间有点长,而且可读性较差,所以我只是把它放在这里。
答案 3 :(得分:1)
随机例子:
AVR GCC有only 32 bit double
s。因此,针对Atmel AVR microcontrollers的GCC偏离了标准。 (如果-mint8
已设置,则deviate even more。)Arduinos基于ATmega328,即AVR。我听说有很多Arduinos“在野外”。
8051/80251系列微控制器具有bit-addressable memory。通过其他地址范围也可以使用不同的宽度访问此存储。内存模型明确是非线性的。即使试图将这些讨论限制在非常成功的部分,也会产生比我愿意在这里转录更长的清单。开始here并继续阅读和关注参考文献。野外的近似数字:太多了。
x86 32位保护模式允许48位段:偏移指针。当针对32位时,Digital Mars C ++会通过__far
,__huge
和__handle
公开这些内容。见Digital Mars's "Choosing a Memory Model"表7.2。所以即使是“x86世界”也有非线性记忆。自Pentium以来就存在这种情况,因此“所有计算机”都是对野外数量的起始估计(并且是正确的数量级)。
非线性存储器的标准示例之一是MC68000。 (奇数地址抛出异常,因为地址总线上的bit0甚至没有引脚。)TI-89和-92计算器是在MC68000上构建的。每个售出数百万(其中许多仍在使用中)。