【问题标题】:Memory align of instances of classes类实例的内存对齐
【发布时间】:2019-11-20 18:14:34
【问题描述】:

我最近在interesting article 阅读了有关性能的文章。

在那里,作者定义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;
}

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

【问题讨论】:

  • 我猜,对齐是 4 个字节。在第一种情况下,shortfloat 不适合 4 个字节,但在第二种情况下,最后三个元素完全适合 4 个字节。

标签: c# .net performance memory-alignment


【解决方案1】:

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

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 => 包字段 => 8 => 8(1+1+6 个空字节)+ 8 = 16 个字节。

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

【讨论】:

    猜你喜欢
    • 2013-02-02
    • 2017-11-12
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    • 2016-07-06
    • 2021-07-30
    • 1970-01-01
    • 2012-05-22
    相关资源
    最近更新 更多