4

让我们从小事做起,假设我需要存储 200 的 const 值,我是否应该一直使用无符号字节呢?

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

或者这一切是否会产生不必要的开销,我最好将我的所有位和短裤替换为这个结构内的整数,这样 CPU 就不必“去寻找”正确的内存块?

4

2 回答 2

8

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

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

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

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

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

于 2013-10-05T16:36:53.170 回答
1

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

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

如果您发现您遇到了性能问题,请使用分析器来确定问题实际出在哪里(它可能不是您想的地方)。如果是内存问题,请确定消耗最多内存的对象并确定可以优化的位置(根据您的示例,如果可能,使用 byte 而不是 int 或 short)。

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

于 2013-10-05T16:50:18.713 回答