SOA (Structs of Arrays)

Goal

The desire is to provide a more data-oriented way to do game object systems without losing language expressivity.

This means retaining the following functionality:

  • is-a / has-a relationships (code re-use via inheritance and composition) 1
  • calling functions with parameter types of the base class (upcasting) 2
  • organizing functions into known slots on the base class (downcasting) 3
  • convenience of an implicit this -> in member functions 4

While being more “data-oriented”—having a clear idea of how you want things to live in memory, in accordance with the principles and guidance outlined in the following references: 5

Problem

In C++, when expressing an is-a / has-a relationship, the following is a typical simple example for organizing game objects:

struct Entity {
    Vector3 position;
    Quaternion orientation;

    unsigned int flags;

    virtual void update() {}
};

struct Door : public Entity {
    float openness_current;
    float openness_target;

    void update() override;
};

struct Human : public Entity {
    char *name;

    void update() override;
}

But this design conceit has introduced problems that grow worse with scale: 6

  • All classes are different sizes
  • Entities can’t be allocated contiguously
  • Cache misses occur

Jai provides the using keyword to allow memory-smart composition. 7

And Jai provides the SOA keyword to organize data into CPU-friendlier Structures of Arrays (SOA): 8 9 10 11

toggle example
print_floats_in_memory.jai
toggle example
soa_entity_test.jai

The AOS keyword allows for declaration-specific overrides to retain Array of Structures style packing when the default has been set to Structures of Arrays. 12


  1. Expressing some kind of is-a relationship or has-a relationship
    “Data-Oriented Demo: SOA, composition.” YouTube, uploaded by Jonathan Blow, Jan 21, 2015, https://youtu.be/ZHqFrNyLlpA?t=655 

  2. C++ lets you call functions with the parameter types of the base class.
    “Data-Oriented Demo: SOA, composition.” YouTube, uploaded by Jonathan Blow, Jan 21, 2015, https://youtu.be/ZHqFrNyLlpA?t=822 

  3. Virtual functions are about going from the base class up to the derived class.
    “Data-Oriented Demo: SOA, composition.” YouTube, uploaded by Jonathan Blow, Jan 21, 2015, https://youtu.be/ZHqFrNyLlpA?t=862 

  4. Some value [in ..] having an implicit this in member functions and you don’t have to write extra code all the time.
    “Data-Oriented Demo: SOA, composition.” YouTube, uploaded by Jonathan Blow, Jan 21, 2015, https://youtu.be/ZHqFrNyLlpA?t=902 

  5. Here are some references in order of approachability about how to structure your program to behave well with respect to memory.
    “Data-Oriented Demo: SOA, composition.” YouTube, uploaded by Jonathan Blow, Jan 21, 2015, https://youtu.be/ZHqFrNyLlpA?t=968 

  6. This packing together of things in memory is part of what makes your game slow, because it has some consequences.
    “Data-Oriented Demo: SOA, composition.” YouTube, uploaded by Jonathan Blow, Jan 21, 2015, https://youtu.be/ZHqFrNyLlpA?t=338 

  7. See Reference > Keywords > Using 

  8. A language like C++ basically assumes your data is going to be in a thing called Array of Structures (AOS): [..] When you’re trying to put things in memory, they go in an array, and each structure in the array is contiguous, so all the members are laid out in order. But most CPUs don’t really want data that way. Most CPUs want things laid out as Structures of Arrays (SOA).
    “Data-Oriented Demo: SOA, composition.” YouTube, uploaded by Jonathan Blow, Jan 21, 2015, https://youtu.be/ZHqFrNyLlpA?t=2870 

  9. In computing, Array of Structures (AoS), Structure of Arrays (SoA) and Array of Structures of Arrays (AoSoA) refer to contrasting ways to arrange a sequence of records in memory, with regard to interleaving, and are of interest in SIMD and SIMT programming.
    https://en.wikipedia.org/wiki/AOS_and_SOA 

  10. If a language is going to be data-oriented, then it should—for example—be easy to put your data in SOA format.
    “Data-Oriented Demo: SOA, composition.” YouTube, uploaded by Jonathan Blow, Jan 21, 2015, https://youtu.be/ZHqFrNyLlpA?t=2927 

  11. The reason that’s faster is because now, in my Entity array, all these flags are going to be next to each other [..] and if you just want to deal with flags, that flags-flags-flags for a long time in memory lets you be very fast.
    “Data-Oriented Demo: SOA, composition.” YouTube, uploaded by Jonathan Blow, Jan 21, 2015, https://youtu.be/ZHqFrNyLlpA?t=3515 

  12. I can make [a struct] that’s SOA by default, but if I want an array of them that’s AOS (for some reason) I can do that.
    “Data-Oriented Demo: SOA, composition.” YouTube, uploaded by Jonathan Blow, Jan 21, 2015, https://youtu.be/ZHqFrNyLlpA?t=3679 

jailang 2019 pixeldroid
https://github.com/pixeldroid/jailang
programming pages theme v0.5.21 (https://github.com/pixeldroid/programming-pages)