我正在寻找.Net中的数据结构,它将异构结构保留在内存中,以便对cpu-cache友好。
此博客中解释了此类数据结构:迭代4 中的T-machine.org。
在.Net中,一组值类型(结构)使数据在内存中保持连续,但这仅适用于非泛型数组。
我试图创建一个ValueType[]
,但结构框是盒装的。因此,引用在内存中是连续的,而不是真实的数据。
经过多次尝试后,我不认为这可能是原生的.Net。我看到唯一可行的解决方案是手动管理字节数组中结构的分类和反序列化,但我认为它不会有效。
您找到了原生解决方案吗?我的更好的解决方案?
编辑1: 我试图实现T-Machine.org博客中描述的实体组件系统。
答案 0 :(得分:2)
没有。在C#中无法进行迭代4 。您无法确定将放置.NET struct
或class
的内存位置。没有类似于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联盟。但是,使用FixedLayout
和FieldOffset
可以创建它们。请注意,它们与引用类型完全不兼容,显然SuperStruct
的大小将是最大可能元素的大小。在这种情况下,32个字节,因为Foo
是20个字节,但在它之前和之后需要一些填充以对齐到8个字节的边界。
显然,您的数组将是SuperStruct
类型。请注意,通过遵循 Iterion 4 示例,StructType
并不是绝对必要的,因为元素的类型是在其他地方写的。