.Net中的数据结构保持异构结构在内存中是连续的

时间:2015-05-03 08:37:20

标签: c# .net data-structures cpu-cache

我正在寻找.Net中的数据结构,它将异构结构保留在内存中,以便对cpu-cache友好。

此博客中解释了此类数据结构:迭代4 中的T-machine.org

在.Net中,一组值类型(结构)使数据在内存中保持连续,但这仅适用于非泛型数组。 我试图创建一个ValueType[],但结构框是盒装的。因此,引用在内存中是连续的,而不是真实的数据。

经过多次尝试后,我不认为这可能是原生的.Net。我看到唯一可行的解​​决方案是手动管理字节数组中结构的分类和反序列化,但我认为它不会有效。

您找到了原生解决方案吗?我的更好的解决方案?

编辑1: 我试图实现T-Machine.org博客中描述的实体组件系统。

1 个答案:

答案 0 :(得分:2)

没有。在C#中无法进行迭代4 。您无法确定将放置.NET structclass的内存位置。没有类似于Placement New of C++的内容。

但请注意,即使迭代4似乎也存在比解决方案更多的问题:

  

此时,我们的迭代非常好,但我们看到了一些反复出现的问题:

     
      
  • 添加/删除组件时重新分配数组(我上面没有涉及 - 如果你不熟悉这个问题,谷歌“C动态数组”)
  •   
  • 碎片化(影响迭代1之后的每次迭代,因为它已经很糟糕了,所以它不会变得更糟糕)
  •   
  • 交叉引用(我跳过)
  •   

<强>但

如果您的struct大小相同, union 技巧就足够了......

public enum StructType
{
    Velocity = 0,
    Position = 1,
    Foo = 2,
    Bar = 3,
}

public struct Velocity
{
    public int Vx;
    public int Vy;
}

public struct Position
{
    public int X;
    public int Y;
    public int Z;
}

public struct Foo
{
    public double Weight;
    public double Height;
    public int Age;
}

public struct Bar
{
    public int ColorR;
    public int ColorG;
    public int ColorB;
    public int Transparency;
}

[StructLayout(LayoutKind.Explicit)]
public struct SuperStruct
{
    [FieldOffset(0)]
    public StructType StructType;

    [FieldOffset(4)]
    public Velocity Velocity;

    [FieldOffset(4)]
    public Position Position;

    [FieldOffset(4)]
    public Foo Foo;

    [FieldOffset(4)]
    public Bar Bar;
}
在C#中“正式”没有C联盟。但是,使用FixedLayoutFieldOffset可以创建它们。请注意,它们与引用类型完全不兼容,显然SuperStruct的大小将是最大可能元素的大小。在这种情况下,32个字节,因为Foo是20个字节,但在它之前和之后需要一些填充以对齐到8个字节的边界。

显然,您的数组将是SuperStruct类型。请注意,通过遵循 Iterion 4 示例,StructType并不是绝对必要的,因为元素的类型是在其他地方写的。