C# Net中的数据结构在内存中保持异构结构的连续性

C# Net中的数据结构在内存中保持异构结构的连续性,c#,.net,data-structures,cpu-cache,C#,.net,Data Structures,Cpu Cache,我正在寻找.Net中的一种数据结构,它在内存中保持异构结构的连续性,以便对cpu缓存友好 这种类型的数据结构在本博客中进行了解释:在迭代4中 在.Net中,值类型数组(结构)在内存中保持数据连续,但这仅适用于非泛型数组。 我试图创建一个ValueType[],但结构已装箱。因此,引用在内存中是连续的,但不是真实的数据 经过多次尝试后,我认为这在.Net中本机是不可能的。我看到的唯一可能的解决方案是手动管理字节数组中结构的序列化和反序列化,但我认为这不会有什么效果 你找到本地解决方案了吗?还是一个

我正在寻找.Net中的一种数据结构,它在内存中保持异构结构的连续性,以便对cpu缓存友好

这种类型的数据结构在本博客中进行了解释:在迭代4中

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

经过多次尝试后,我认为这在.Net中本机是不可能的。我看到的唯一可能的解决方案是手动管理字节数组中结构的序列化和反序列化,但我认为这不会有什么效果

你找到本地解决方案了吗?还是一个比我更好的解决方案

编辑1: 我正试图实现博客中描述的实体组件系统。

否。在C#中无法实现迭代4。您无法决定.NET
struct
class
将放在内存中的什么位置。没有什么类似的

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

在这一点上,我们的迭代非常好,但我们看到一些重复出现的问题:

  • 在添加/删除组件时重新分配阵列(我没有在上面介绍过——如果您不熟悉这个问题,请使用google“C dynamic array”)
  • 碎片化(影响迭代1之后的每个迭代,这不会变得更糟,因为它已经非常糟糕了)
  • 交叉引用(我跳过了)
但是

如果你有差不多相同大小的
struct
,联合技巧就足够了

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
可以创建它们。请注意,它们与引用类型完全不兼容,
上部结构的大小显然是最大可能元素的大小。在本例中为32字节,因为
Foo
为20字节,但前后需要一些填充以对齐8字节边界


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

如果您需要的数据结构类型是固定的,您可以将它们放在另一个结构中。。。因此
struct PositionVelocity{Position Pos;Velocity Vel}
您可以使用两个不同的数组,这也可以减少填充,如果不是“big struct”的所有字段都同样热,这一点尤其好。不管怎样,你能更详细地说明你在做什么吗?然后我们可以给出一个更集中的解决方案。@xanatos不幸的是,在编译时我不知道所有的结构类型。另外,我可以先有一个位置,然后是一个速度,然后是另一个速度,谢谢,我是这么想的,但我不能百分之百肯定。我想我将使用多个数组,每种结构类型一个。这样做我将有缓存未命中(当访问系统中的多个组件类型时),但小于组件作为类。@Romain Wait。。。等待如果只需要保留非引用类型,可以使用union技巧。给我五分钟……如果它们的尺寸不一样,那就浪费空间了though@Romain看看这个例子。@harold清楚地说:-)这不是完美的魔法子弹。如果您有各种大小相似的
struct
,它就可以工作。