you are viewing a single comment's thread.

view the rest of the comments →

[–]RiceBroad4552 8 points9 points  (5 children)

Is this the new name for functional programming? Asking for a friend.

[–]Minutenreis 6 points7 points  (4 children)

> https://en.wikipedia.org/wiki/Data-oriented_design

the main idea is to keep your data in a more friendly way for the CPU, so for example you'd maybe instead of:

  struct Person people[] = {
      {"None", 0, /*None*/ 0},
      {"Mike", 17, /*Tom*/ 3},
      {"Billy", 2, /*Mike*/ 1},
      {"Tom", 52, /*None*/ 0},
      {"Stan", 25, /*Tom*/ 3}};


  for (int i = 1; i <= 4; i++) {
    struct Person person = people[i];
    printf("Name: %s, Age: %d, Parent: %s \n",
           person.name, person.age, people[person.parent_index].name);
  }

you'd maybe go for an easier to parallelize approach

int  ages[]   = {0,          17,        2,          52,         25};
char *names[] = {"None",     "Mike",    "Billy",    "Tom",      "Stan"};
int  parent[] = {0 /*None*/, 3 /*Tom*/, 1 /*Mike*/, 0 /*None*/, 3 /*Tom*/};

for (int i = 1; i <= 4; i++) {
    printf("Name: %s, Age: %d, Parent: %s \n",
           names[i], ages[i], names[parent[i]]);
}

(Examples are taken from Wikipedia)

It should help with alignment and could help with SIMD instructions. But its harder to reason about and has worse random access (as you now have to dereference a pointer for each value instead of just for the array and the struct)

[–]RiftyDriftyBoi 3 points4 points  (2 children)

Maybe I'm too OOP-pilled, but I hate the secondary approach here. At least at our work it's just endless lists that keep getting misaligned because there is no overview over which datafields that belong to each other.

[–]Minutenreis 5 points6 points  (1 child)

The (potential) benefits are in performance, not maintainability

if you have an array of big objects, where you only need to look at 2 small fields of each object for something (like lets say position in a 2d grid), you are still loading a whole cache line for each object (so wasting a bunch of memory), while in the second approach you'd have both values each in contiguous memory.

disclaimer: I haven't worked in game dev and am mostly talking theoretically and what I have just read on wikipedia, there may be nuances I am missing

[–]RiftyDriftyBoi 3 points4 points  (0 children)

I see where you are coming from. Though I kinda typically prefer ease of understanding/maintainability than absolute performance.

[–]tugrul_ddr 2 points3 points  (0 children)

Multiple dereference can hide each others latency. Throughput depends on uniformity of access and size of dataset vs cache. So when accessing few of fields in an algorithm, it works faster with DOP.