CLR顺序结构布局:对齐和大小 [英] CLR sequential structs layout: aligning and size

查看:156
本文介绍了CLR顺序结构布局:对齐和大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所有结构 S在C#中默认情况​​下被视为 [StructLayout(LayoutKind.Sequential)] -marked值类型。所以,让我们结构的S一定数量和检查这个尺寸结构 S:

All structs in C# by default are treated as [StructLayout(LayoutKind.Sequential)]-marked value types. So lets take some number of structs and inspect sizes of this structs:

using System;
using System.Reflection;
using System.Linq;
using System.Runtime.InteropServices;

class Foo
{
  struct E { }
  struct S0 { byte a; }
  struct S1 { byte a; byte b; }
  struct S2 { byte a; byte b; byte c; }
  struct S3 { byte a; int b; }
  struct S4 { int a; byte b; }
  struct S5 { byte a; byte b; int c; }
  struct S6 { byte a; int b; byte c; }
  struct S7 { int a; byte b; int c; }
  struct S8 { byte a; short b; int c; }
  struct S9 { short a; byte b; int c; }
  struct S10 { long a; byte b; }
  struct S11 { byte a; long b; }
  struct S12 { byte a; byte b; short c; short d; long e; }
  struct S13 { E a; E b; }
  struct S14 { E a; E b; int c; }
  struct S15 { byte a; byte b; byte c; byte d; byte e; }
  struct S16 { S15 b; byte c; }
  struct S17 { long a; S15 b; }
  struct S18 { long a; S15 b; S15 c; }
  struct S19 { long a; S15 b; S15 c; E d; short e; }
  struct S20 { long a; S15 b; S15 c; short d; E e; }

  static void Main()
  {
    Console.WriteLine("name: contents => size\n");
    foreach (var type in typeof(Foo).GetNestedTypes(BindingFlags.NonPublic))
    {
      var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
      Console.WriteLine("{0}: {2} => {1}", type.Name, Marshal.SizeOf(type),
        string.Join("+", fields.Select(_ => Marshal.SizeOf(_.FieldType))));
    }
  }
}

输出是(在x86 / x64的相同):

Output is (the same on x86/x64):

name: contents => size

E:  => 1
S0: 1 => 1
S1: 1+1 => 2
S2: 1+1+1 => 3
S3: 1+4 => 8
S4: 4+1 => 8
S5: 1+1+4 => 8
S6: 1+4+1 => 12
S7: 4+1+4 => 12
S8: 1+2+4 => 8
S9: 2+1+4 => 8
S10: 8+1 => 16
S11: 1+8 => 16
S12: 1+1+2+2+8 => 16
S13: 1+1 => 2
S14: 1+1+4 => 8
S15: 1+1+1+1+1 => 5
S16: 5+1 => 6
S17: 8+5 => 16
S18: 8+5+5 => 24
S19: 8+5+5+1+2 => 24
S20: 8+5+5+2+1 => 24

看着这导致我无法理解的布局(田心和总大小)用于顺序结构规则集CLR。有人可以解释我的这种行为?

Looking at this results I can't understand the layout (fields aligning and total size) ruleset CLR used for sequential structs. Can somebody explain me this behavior?

推荐答案

所有的字段都根据不同的类型一致。本机类型( INT 字节等)都统一由它们的大小。例如, INT 将永远在4字节的倍数,而一个字节可以在任何地方。

All the fields are aligned depending on their type. The native types (int, byte, etc.) are all aligned by their size. For example, an int will always be at a multiple of 4 bytes in, while a byte can be anywhere.

如果较小的领域来之前的 INT ,填充将在必要时确保添加的 INT 是正确对齐以4个字节。这也就是为什么 S5 (1 + 1 + 4 = 8)和 S8 (1 + 2 + 4 = 8)将填充,并最终同尺寸:

If smaller fields come before an int, padding will be added if necessary to ensure the int is properly aligned to 4 bytes. This is why S5 (1+1+4 = 8) and S8 (1+2+4 = 8) will have padding and end up the same size:

[1][1][ ][ ][4] // S5
[1][ ][ 2  ][4] // S8

此外,对结构本身继承了其最对齐字段(即的对齐 S5 S8 INT 是最对齐的领域,所以两者有4字节的对齐)。对准继承这样的,这样,当你有结构的数组,这一切的一切的结构的字段将被正确对齐。所以,4 + 2 = 8

Additionally, the struct itself inherits the alignment of its most-aligned field (ie. for S5 and S8, int is the most-aligned field, so both of them have an alignment of 4). Alignment is inherited like this so that when you have an array of structs, all the fields in all the structs will be properly aligned. So, 4+2 = 8.

[4][2][ ][ ] // starts at 0
[4][2][ ][ ] // starts at 8
[4][2][ ][ ] // starts at 16

的通知4总是由4对齐如果没有最对齐场继承,数组中的所有其他元素也有其 INT 6个字节,而不是对准4:

Notice the 4 is always aligned by 4. Without inheriting from the most-aligned field, every other element in an array would have its int aligned by 6 bytes instead of 4:

[4][2] // starts at 0
[4][2] // starts at 6 -- the [4] is not properly aligned!
[4][2] // starts at 12

这将是非常糟糕的,因为不是所有的架构允许未对齐的内存地址读取,甚至那些确实有做这一个(可能相当大,如果在高速缓存行边界)的性能损失。正确的定位是很重要的!

This would be very bad because not all architectures allow reading from unaligned memory addresses, and even the ones that do have a (potentially quite large, if on a cache line boundary) performance penalty for doing it. Proper alignment is very important!

您会经常看到聪明的本土codeRS让所有的这一点,同时奠定了它们的结构,排序的所有字段从最大到最小,努力保持填充,因而结构尺寸,到最低限度。

You will often see clever native coders keep all of this in mind while laying out their structures, sorting all fields from largest to smallest in an effort to keep padding, and thus struct size, to a minimum.

这篇关于CLR顺序结构布局:对齐和大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆