现在的位置: 首页 > 综合 > 正文

学习随笔 一 SOA AOS 面向对象与面向数据

2018年01月16日 ⁄ 综合 ⁄ 共 2040字 ⁄ 字号 评论关闭

SOA 数组的结构与AOS结构的数组,是面向数据和面向对象设计的区别之一。

在需要高频率(如渲染循环中)访问数据的时候,一般情况下SOA的效率高于AOS,因为将需要频繁访问的数据连续存放会大大提高访问速度。虽然AOS的结构可能更适合面向对象设计,但是在高度依赖效率的地方应该使用SOA

引用大家都在说的一句话:一开始写程序用struct (c方式的编程,面向数据的编程) 后面开始用class (为了改善程序结构,OO方式的编程) 最后又开始用struct(为了性能!)

 

引用一篇文章来说明SOA 与 AOS(面向数据设计与面向对象设计) 两种方式的区别

My understanding of Data Oriented Design is that it is about organizing your data for efficient processing. Especially with respect to cache misses etc. Data Driven Design on the other hand is about letting data control a lot of your programs behavior

 

Say you have ball objects in your application with properties such as color, radius, bounciness, position etc. In OOP you would describe you balls like this:

class Ball {
  Point  pos;
  Color  color;
  double radius;

  void draw();
};

And then you would create a collection of balls like this:

vector<Ball> balls;

In Data Oriented Design however you are more likely to write the code like this:

class Balls {
  vector<Point>  pos;
  vector<Color>  color;
  vector<double> radius;

  void draw();
};

As you can see there is no single unit representing one Ball anymore. Ball objects only exist implicitly. I don't want to rewrite the article so I am not going to go into detail why one does it like this, but it can have many advantages performance wise.
Usually we want to do operations on many balls at the same time. Hardware usually want large continuous chunks of memory to operate efficiently. Secondly you might do operations that affects only part of a balls properties. E.g. if you combine the colors of
all the balls in various ways, then you want your cache to only contain color information. However when all ball properties are stored in one unit you will pull in all the other properties of a ball as well. Even though you don't need them.

Say a ball each ball takes up 64 bytes and a Point takes 4 bytes. A cache slot takes say 64 bytes as well. If I want to update the position of 10 balls I have to pull in 10*64 = 640 bytes of memory into cache and get 10 cache misses. If however I can work
the positions of the balls as separate units, that will only take 4*10 = 40 bytes. That fits in one cache fetch. Thus we only get 1 cache miss to update all the 10 balls. These numbers are arbitrary I assume a cache block is bigger.

But it illustrates how memory layout can have severe effect cache hits and thus performance. This will only increase in importance as the difference between CPU and RAM speed widens.

 

 

抱歉!评论已关闭.