使用哪种数据类型? CPU如何读取它们?

时间:2013-10-05 16:18:11

标签: c#

让我们从小开始,说我需要存储一个200的const值,我应该总是使用无符号字节吗?

我猜这只是一件小事。但是结构呢?构建我的结构是否明智,以便32位系统上的32可以分割?假设我需要遍历一个非常大的结构数组,如果结构由34位或64位组成,那么它是否重要?如果我可以从34位结构中挤出2位,我会认为它会获得很多收益吗?

或者所有这些都会产生不必要的开销,我最好将所有的位和短路替换为这个结构中的整数,这样CPU就不必“寻找”正确的内存块了吗?

2 个答案:

答案 0 :(得分:8)

这是一个强大的处理器实现细节,CLR和抖动已经做了大量工作,以确保您的数据类型是最佳的,以获得最佳的程序性能。例如,从来没有一个结构占用34位的情况,CLR设计选择已经确保您可以使用在现代处理器上运行良好的类型。

结构布局是最优的,并且涉及取决于数据类型的对齐选项。例如, int 将始终与偏移量对齐,该偏移量是4的倍数。这使得处理器可以轻松地读取 int ,它不需要多路复用未对齐的字节返回到int并避免了值跨越cpu缓存行并需要从多个内存总线读取粘合在一起的情况。某些处理器事件将未对齐的读取和写入视为致命错误,这是您的计算机中没有安装Itanium的原因之一。

因此,如果你有一个包含字节和int的结构,那么你最终会得到一个数据类型,该数据类型占用8个字节,不使用3个字节,即字节和int之间的字节。这些未使用的字节称为 padding 。在结构的末尾也可以有填充,以确保在将它们放入数组时对齐仍然是最佳的。

将单个变量声明为字节是可以的,Intel / AMD处理器需要相同的时间来读取/写入一个32位int。但是使用 short 是不行的,这需要cpu指令中的额外字节(大小覆盖前缀)并且可能花费额外的cpu周期。实际上,由于对齐规则,您通常不会保存任何内存。如果可以将字节与另一个字节组合使用,则只使用字节。一个字节数组很好,一个包含多个字节成员的结构很好。你的例子不是,当你声明它 int 时,它也能正常工作。

在C#代码中使用小于int的类型可能很笨拙,MSIL代码模型是基于int的。像+和 - 这样的基本运算符只为int和更大版本定义,没有较小类型的运算符。因此,您最终必须使用强制转换将结果截断为较小的大小。最佳点是 int

答案 1 :(得分:1)

哇,这真的取决于一堆东西。你关注性能还是内存?如果它的性能通常会更好地保持“自然”字长对齐。因此,例如,如果您使用64位处理器使用64位整数,则在64位边界上对齐可提供最佳性能。我不认为C#对这类事物有任何保证(它意味着从硬件中保持抽象)。

这就是说有一条非正式的规则说“避免过早优化的罪”。在C#中尤其如此。如果您没有性能或内存问题,请不要担心。

如果您发现性能问题,请使用分析器确定问题的实际位置(可能不在您认为的位置)。如果是内存问题,请确定消耗最多内存的对象并确定可以优化的位置(根据您的示例使用字节而不是int或short,如果可能)。

如果您真的不得不担心这些细节,您可能需要考虑使用C ++,在那里您可以更好地控制内存使用(例如,您可以分配大块内存而不进行初始化),访问位域等等。