Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data structure in .Net keeping heterogeneous structs contiguous in memory

I'm looking for a data structure in .Net which keep heterogeneous structs contiguous in memory in order to be cpu-cache-friendly.

This type of data structure is explained in this blog : T-machine.org at the Iteration 4.

In .Net an array of value types (structs) keeps data contiguous in memory, but this is only working for a no-generic array. I tried to create a ValueType[], but structs are boxed. So the references are contiguous in memory but not the real data.

After many tries I don't think this is possible natively in .Net. The only possible solution I see, it's to manually managed the seralization and deserialization of structs in a byte array, but I don't think it will be performant.

Did you find a native solution? or a better solution that mine?

Edit 1: I'm trying to implement an entity-component-system as described in the T-Machine.org blog.

like image 551
Romain Rastel Avatar asked May 03 '15 08:05

Romain Rastel


People also ask

Which data structure is contiguous in memory?

In contiguous structures, terms of data are kept together in memory (either RAM or in a file). An array is an example of a contiguous structure. Since each element in the array is located next to one or two other elements.

Which data structure is used to store homogeneous data elements?

The array is a data structure used to store homogeneous elements at contiguous locations. The size of an array must be provided before storing data.

What is a contiguous data structure?

Contiguous data structure is a method of storing data in contiguous, or adjoining, sectors of memory. When information is written, if there is enough space, the information is written contiguous. However, if there is not enough available space, data is written to multiple places which makes it non-contiguous.

Which linear data structure uses continuous memory?

Array Data Structure In an array, elements in memory are arranged in continuous memory. All the elements of an array are of the same type.


1 Answers

No. There is no way to do Iteration 4 in C#. You can't decide where in memory a .NET struct or class will be put. There is nothing similar to Placement New of C++.

But note that even Iteration 4 seems to have more problems than solutions:

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)

but

if you have struct of around the same size, the union trick could be enough...

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;
}

"officially" in C# there are no C unions. But thorugh the use of FixedLayout and FieldOffset you can create them. Note that they are totally incompatible with reference types, and clearly the size of the SuperStruct will be the size of the biggest possible element. In this case, 32 bytes, because Foo is 20 bytes, but there is some padding needed before and after it to align to the 8 bytes boundary.

Clearly your array would be of SuperStruct types. Note that by following the Iterion 4 example, the StructType isn't strictly necessary, because the types of the elements is written in other places.

like image 51
xanatos Avatar answered Oct 13 '22 12:10

xanatos