我正在寻找 .Net 中的数据结构,它使异构结构在内存中保持连续,以便对 cpu 缓存友好。
此博客中解释了这种类型的数据结构:T-machine.org在第 4 次迭代。
在 .Net 中,值类型(结构)数组使数据在内存中保持连续,但这仅适用于非泛型数组。
我试图创建一个 ValueType[]
,但结构被装箱了。所以引用在内存中是连续的,但不是真实数据。
经过多次尝试后,我认为这在 .Net 中是不可能的。我看到的唯一可能的解决方案是手动管理字节数组中结构的序列化和反序列化,但我认为它的性能不佳。
您找到原生解决方案了吗?还是我的更好的解决方案?
编辑 1: 我正在尝试实现实体组件系统,如 T-Machine.org 中所述博客。
最佳答案
没有。无法在 C# 中执行迭代 4。您无法决定将 .NET struct
或 class
放在内存中的什么位置。没有类似 Placement New of C++ 的东西.
但请注意,即使是迭代 4,问题似乎也多于解决方案:
At this point, our iterations are quite good, but we’re seeing some recurring problems:
- Re-allocation of arrays when Components are added/removed (I’ve not covered this above – if you’re not familiar with the problem, google “C dynamic array”)
- Fragmentation (affects every iteration after Iteration 1, which doesn’t get any worse simple because it’s already as bad as it could be)
- Cross-referencing (which I skipped)
但是
如果您有大小相同的 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
并不是绝对必要的,因为元素的类型是在其他地方编写的。
关于c# - .Net 中的数据结构在内存中保持异构结构连续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30011801/