1

例如,在 32 位处理器的情况下,一个字是 4 字节长。是否也可以使用 5 字节字或其他字?

4

2 回答 2

1

是否也可以使用 5 字节字或其他

是的。您甚至可以通过位字段仅使用几位而不是整个字节/字。从技术上讲,编译器可以支持任何架构上的任何整数大小,例如 16 位计算机上的 12 位、30 位或 96 位 int。事实上,Clang 刚刚为具有任意位宽的整数提供了一个新的扩展,称为_ExtInt. 也可以看看

为什么不是 40 位或其他数字?

性能会受到很大影响。我们需要更多指令来处理非本地整数大小。如果大小小于一个字,则编译器需要发出按位指令来屏蔽剩余的位。在相反的情况下,我们需要多个指令来处理多个单词

另一个重要的事情是错位。当变量的地址是其大小的倍数或至少是数据总线宽度/字大小的倍数时,现代 CPU 的工作效率更高。使用奇数大小的变量很尴尬


也就是说,存在许多具有 40 位类型的 32 位架构,例如TI C6000TI C5500 DSP

long

  • C6000 COFF 为40 位或 5 字节

[...] 并且 C5500 具有40 位long long

TI 编译器中的 C89 支持

这是因为那些 DSP 有一个特殊的 40 位累加器,允许将 32 位数字相加 256 次而不会溢出。但是为什么不直接使用 64 位累加器呢?这将需要更大的 ALU,需要更多的功率并且运行速度更慢(因为更大的区域意味着硬件组件之间的距离更长,并且在大数字上运行比在较小的数字上运行慢),这在为性能而设计的 DSP 中是不可接受的(可能还有力量)

...例如,德州仪器公司的 TMS320C6000,一个 DSP 处理器,使用 32 位表示类型int,使用 40 位表示类型long(这种选择并不少见)。那些使用 24 位来表示类型的处理器(通常是 DSP)int,往往使用 48 位来表示类型long。24/48 位整数类型表示的使用可以由 32/64 位整数类型表示不具成本效益的应用需求驱动。

新 C 标准(节选材料):经济和文化评论

事实上,40 位 int 在 DSP 中很常见(其他例子是BlackfinSHARC)。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 的解决方案

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];
};
于 2020-01-27T17:29:54.937 回答
0

从历史上看,有一些计算机的字长不是 2 的幂,如这个字长表。然而,最终人们发现,当地址大小是 2 的幂时,地址算术更容易实现。

考虑一个操作,例如“向前跳 14 个单词”。如果字长是 2 的幂,比如 64,则电路需要将数字 14 移动log(64)/log(2)=6并加上ip,这可以在 1 个周期内轻松完成。但是,如果字长为 36,如 IBM 701,则数字 14 必须乘以 36,这将花费更多周期。鉴于将整数乘以字长是一种非常常见的操作,因此减速将是显着的。

于 2015-07-09T05:57:36.320 回答