C 为什么数据结构的大小通常为2^n?

C 为什么数据结构的大小通常为2^n?,c,data-structures,size,buffer,C,Data Structures,Size,Buffer,有历史原因吗?我见过很多次类似于char foo[256]或#定义基本单位大小1024。甚至我也只使用2n大小的缓冲区,主要是因为我认为它看起来更优雅,这样我就不必考虑具体的数字。但我不太确定这是否是大多数人使用它们的原因,请提供更多信息 由于电子学中基数2算法的简单性(也可以理解为成本):左移(乘以2),右移(除以2) 在CPU领域,许多构造都围绕着基2算法展开。访问内存结构的总线(控制和数据)通常在电源2上对齐。电子设备(如CPU)中逻辑实现的成本,使得base 2中的算术变得引人注目 当然

有历史原因吗?我见过很多次类似于char foo[256]
#定义基本单位大小1024
。甚至我也只使用2n大小的缓冲区,主要是因为我认为它看起来更优雅,这样我就不必考虑具体的数字。但我不太确定这是否是大多数人使用它们的原因,请提供更多信息

由于电子学中基数2算法的简单性(也可以理解为成本):左移(乘以2),右移(除以2)

在CPU领域,许多构造都围绕着基2算法展开。访问内存结构的总线(控制和数据)通常在电源2上对齐。电子设备(如CPU)中逻辑实现的成本,使得base 2中的算术变得引人注目

当然,如果我们有模拟计算机,情况就不同了。


仅供参考:位于X层的系统的属性是位于X层以下的系统的服务器层属性的直接结果,即层
例如,可以在“编译器”级别操作的属性是继承的,即CPU中的电子设备。缓存线通常是2的倍数(通常是32或64)。如果数据是该数字的整数倍,则能够适应(并充分利用)相应数量的缓存线。可以打包到缓存中的数据越多,性能越好。。因此,我认为以这种方式设计结构的人正在为此进行优化。

可能有很多原因,尽管很多人会像你说的那样只是出于习惯而这样做

它非常有用的一个地方是循环缓冲区的有效实现,特别是在%运算符昂贵的体系结构上(那些没有硬件划分的体系结构-主要是8位微控制器)。通过使用2^n缓冲区,在这种情况下,模仅是位屏蔽高位的情况,或者在256字节缓冲区的情况下,仅使用8位索引并使其环绕


在其他情况下,与页面边界、缓存等对齐可能会在某些架构上提供优化的机会,但这是非常特定于架构的。但这可能只是因为这样的缓冲区为编译器提供了优化的可能性,所以所有其他因素都是相同的,为什么不呢?

除了大家提到的以外,另一个原因是,SSE指令需要多个元素,输入的元素数总是二的幂。将缓冲区设置为二次幂可以保证不会读取未分配的内存。但这仅适用于实际使用SSE指令的情况

但我认为最终,在大多数情况下,压倒性的原因是程序员喜欢二的幂

哈希表,按页分配 这对哈希表非常有帮助,因为您计算的索引模大小是2的幂,如果该大小是2的幂,则可以使用简单的按位and或
&
计算模,而不是使用执行
%
运算符的速度慢得多的除法类指令

看看一本旧的英特尔i386书籍,
是2个周期,
div
是40个周期。尽管1000倍的总循环时间往往掩盖了即使是最慢的机器操作的影响,但由于分工的更大的基本复杂性,目前仍存在差距

还有一段时间,malloc开销偶尔会被大量避免。直接从操作系统获得的分配将是(仍然是)特定数量的页面,因此二次幂可能会最大限度地利用分配粒度


而且,正如其他人所指出的,程序员喜欢二的幂。

我本来打算使用移位参数,但可以想出一个很好的理由来证明它

二次幂的缓冲区的一个优点是,循环缓冲区处理可以使用简单的AND而不是除法:

#define BUFSIZE 1024

++index;                // increment the index.
index &= BUFSIZE;       // Make sure it stays in the buffer.

如果不是二的幂,那么就必须进行分割。在过去(目前使用的是小型芯片),这很重要。

页面大小为2的幂也是很常见的


在linux上,我喜欢使用getpagesize()来执行诸如对缓冲区进行分块并将其写入套接字或文件描述符之类的操作。

我可以想到一些不经意的原因:

  • 2^n是所有计算机大小中非常常见的值。这与计算机中位的表示方式(2个可能的值)直接相关,这意味着变量往往具有边界为2^n的值范围
  • 由于上述原因,您通常会发现值256是缓冲区的大小。这是因为它是一个字节中可以存储的最大数字。因此,如果要将字符串与字符串的大小一起存储,那么将其存储为:
    size\u BYTE+ARRAY
    ,其中大小字节告诉您数组的大小,将是最有效的。这意味着阵列可以是1到256之间的任意大小
  • 很多时候,大小是根据物理因素来选择的(例如,操作系统可以选择的内存大小与CPU寄存器的大小有关),这些也将是特定数量的位。也就是说,您可以使用的内存量通常为2^n(对于32位系统,为2^32)
  • 这些值可能存在性能优势/一致性问题。大多数处理器一次可以访问一定数量的字节,因此,即使您有一个大小为(比如说)20位的变量,32位处理器仍将读取32位,不管是什么。因此,使用JU的效率通常要高出数倍