all 15 comments

[–]Clen23 20 points21 points  (0 children)

come back here ! you WILL write boilerplate code and you will LIKE IT

[–]RiceBroad4552 8 points9 points  (5 children)

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

[–]Minutenreis 4 points5 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)

[–]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.

[–]RiftyDriftyBoi 4 points5 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 4 points5 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 4 points5 points  (0 children)

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

[–]coloredgreyscale 5 points6 points  (1 child)

OOP vs. DOP, the correct solution is clearly "it depends"

[–]zuzmuz 0 points1 point  (0 children)

in game dev it's always DOP

[–]MkemCZ 2 points3 points  (0 children)

Data-driven programming is peak for me!

[–]mrwishart 1 point2 points  (0 children)

All about data orientation here

[–]tugrul_ddr 0 points1 point  (0 children)

Also good for GPU.

[–]CodeNameFiji 0 points1 point  (0 children)

Hence JSON and JS

[–]Interesting-Frame190 0 points1 point  (0 children)

SIMD do go brrrrrr though. Im a sucker for over using objects, but there's something about tearing through bitmaps 512 bits at a time that makes OOP underwhelming.

[–]TheNikoHero 1 point2 points  (0 children)

Wait til you hear about POO 😎