我正在阅读C#中的非托管代码,并遇到以下问题: -
在C#程序中,CLR使用字段标记查找偏移量 C字段名称直接编译为偏移量。对于访问速度,每个字段都放置在一个字段大小倍数的偏移处 然而,该乘数限制为最大x个字节,其中x是“包大小”。
我的问题是什么是包装尺寸?
答案 0 :(得分:4)
我将把字段对齐的细节作为一个给定的内容,包括在devshorts的引用中。包大小设置是编译器停止尝试保持字段对齐的地方,因为它太大了。
它是一个编译器设置或本机代码中的#pragma。英特尔处理器上的一个棘手问题,因为它们非常灵活,允许未对齐的数据,几乎没有惩罚。包装尺寸为8是一种非常常见的默认值,几乎总是正确的。有时它是1或4.你的[StructLayout]声明中的Pack属性必须匹配,如果没有,那么你将有很好的读取垃圾的几率,因为你将在错误的内存位置读取一个字段。
答案 1 :(得分:2)
在计算机体系结构中,让事情变得更快byte aligned。当语言规范谈论包大小时,这就是说编译器会根据事物的对齐方式自动为数据大小创建更大的插槽。这意味着有时你认为是2字节字段,实际上可以在内存中的4字节插槽。如果你想减少存储空间大小,换取cpu减速,你可以调整包大小。
检查包装上的msdn以获取更多信息。
引用此tutorial:
历史上,内存是字节可寻址的,并按顺序排列。 如果 存储器被安排为一个字节宽度的单个存储体,即处理器 需要发出4个内存读取周期来获取整数。它更多 在一个存储周期中读取所有4个字节的整数是经济的。要采取 这样的优势,内存将被安排为4组的一组 如上图所示。
内存寻址仍然是顺序的。如果银行0占用一个 地址X,存储区1,存储区2和存储区3将位于(X + 1),(X + 2)和 (X + 3)地址。如果在X地址上分配了4个字节的整数 (X是4的倍数),处理器只需要一个存储周期 读完整数。
如果,,如果整数是在除以外的地址分配的话 它是4的倍数,跨越两排银行,如图所示 下图。这样的整数需要两个存储器读取周期来获取 数据。
...
变量的数据对齐处理数据的存储方式 这些银行。例如,int在32位上的自然对齐 机器是4个字节。当数据类型自然对齐时,CPU 以最小的读取周期取出它。
类似地,short int的自然对齐是2个字节。这意味着,a short int可以存储在bank 0 - bank 1对或bank 2 - bank 3中 对。 double需要8个字节,并占用内存中的两行 银行。任何双重错位都会强制超过两个读取周期 获取双数据。
请注意,双变量将在32字节边界上分配 位机并需要两个存储器读周期。在64位机器上, 根据库数,双变量将分配在8字节上 边界并且只需要一个存储器读周期。
虽然语言不同,但概念是相同的