例如,在32位处理器的情况下,字是4字节。是否也可以使用5个字节的单词或其他字。
答案 0 :(得分:1)
是否还可以使用5字节字或其他字
是的。您甚至可以通过bit fields仅使用几位,而不用整个字节/字。从技术上讲,编译器可以在任何体系结构上支持任何整数大小,例如16位计算机上的12位,30位或96位int。实际上,Clang刚刚对具有任意位宽的整数进行了扩展,称为_ExtInt
。另请参见
为什么不是40位或其他数字?
性能会受到很大的影响。我们需要 更多说明 来处理非本地整数大小。如果大小小于一个字,则编译器需要发出按位指令以掩盖其余位。相反,我们需要多个指令来处理多个单词
另一个重要的事情是misalignment。当变量的地址是其大小的倍数或至少是数据总线宽度/字长的倍数时,现代CPU可以更有效地工作。使用奇数大小的变量很尴尬
也就是说,存在许多40位类型的32位架构,例如TI C6000或TI C5500 DSP
long
是
- 40位或C6000 COFF的5个字节
[...]和C5500具有 40位
long long
这是因为这些DSP具有特殊的40位累加器,可以将32位数字相加256次而不会溢出。但是,为什么不只使用64位累加器呢?这将需要更大的ALU,需要更多的功率并运行得更慢(因为更大的面积意味着硬件组件之间的距离更长,并且与较小的组件相比,大量组件的运行要慢),这在为性能而设计的DSP中是不可接受的(可能还有力量)
...例如,DSP处理器德州仪器(TI)TMS320C6000使用32位表示类型
int
,使用40位表示类型long
(这种选择并不罕见)。那些使用24位来表示类型int
的处理器(通常是DSP),通常使用48位来表示类型long
。应用程序要求可以使用24/48位整数类型表示形式,而32/64位整数类型表示形式并不划算。The New C Standard (Excerpted material): An Economic and Cultural Commentary
事实上,在DSP中40位int很常见(其他示例为Blackfin和SHARC)。 SHARC甚至具有80位累加器,因此您可以添加很多64位值,而不必担心溢出
但是您不需要特殊的体系结构或特殊的编译器支持。如果确实需要,您仍然可以使用40位变量,例如,当您使用巨大的数组时,其中64位整数会使它太大而无法容纳在主内存中,而较少的项适合缓存。最简单的方法是禁用与#pragma pack
或__attribute__((packed))
struct int40_t {
int64_t : 40;
} __attribute__((packed));
int40_t myArray[200] __attribute__((packed));
或从简单的char数组(基于cmm's solution)访问值
unsigned char _5byteInts[5*size+3]; // +3 avoids overfetch of last element
int64_t get5byteInt(size_t index)
{
int64_t v = 0;
memcpy(&v, &_5byteInts[index*5], 5); // little endian
return (v << 24) >> 24;
}
void set5byteInt(size_t index, int64_t value)
{
memcpy(&_5byteInts[index*5], &value, 5); // little endian
}
但是,如果不进行统一访问,这些操作将导致体系结构性能下降。您可以将四个40位整数打包到单个20字节结构中,以更好地对齐
struct four_int40s {
uint32_t low[4];
uint8_t hi[4];
};
答案 1 :(得分:0)
历史上,有一些计算机的字大小不是2的幂,如Table of word sizes所示。然而,最终人们发现,当地址大小为2的幂时,地址算法更容易实现。
考虑诸如“向前跳14个字”之类的操作。如果字大小是2的幂,比如64,则电路需要将数字14移位log(64)/log(2)=6
并添加到ip
,这可以在1个周期内轻松完成。但是,如果字大小为36,如在IBM 701中那么,则数字14必须乘以36,这将需要更多周期。鉴于将整数乘以字大小是一种非常常见的操作,减速将是显着的。