首页 > 解决方案 > 类实例的内存对齐

问题描述

我最近阅读了有关性能的有趣文章。

在那里,作者定义struct如下:

public struct DecisionTreeNode
{
  public short ShortValue;
  public float FloatValue;
  public byte ByteVal1;
  public byte ByteVal2;
}

struct是8个字节。

一切都清楚,但随后他建议为了获得性能,作者写道:

这个 [memory] ​​对齐问题意味着加载未对齐的值可能会更加昂贵。幸运的是,修复非常简单,您只需在类定义中交换字段的顺序。

所以他这样做:

public struct DecisionTreeNode
{
  public float FloatValue;
  public short ShortValue;
  public byte ByteVal1;
  public byte ByteVal2;
}

类中字段的顺序如何影响在内存中存储实例的方式?它如何影响提到的对齐?

标签: c#.netperformancememory-alignment

解决方案


你在这里有一个很好的解释:

https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.structlayoutattribute.pack?view=netframework-4.7

https://kalapos.net/Blog/ShowPost/DotNetConceptOfTheWeek13_DotNetMemoryLayout

一切都与 Pack 字段有关(是其最大元素的大小或指定的打包大小属性 => [StructLayout(LayoutKind.Sequential, Pack=X)] 以较小者为准)。

根据 Pack 字段,结构将按顺序将字段分组为 Pack 大小并添加空字节以适应 Pack 字段。

struct => 1byte + 8byte + 1byte => 打包字段 => 8 => 8 + 8 + 8 = 24bytes

struct => 1byte + 1byte + 8byte => Pack 字段 => 8 => 8(1+1+6 个空字节)+ 8 = 16 个字节。

如您所见,始终使用 Pack 字段大小对字段进行分组。


推荐阅读