rye*_*guy 139 data-oriented-design
我正在阅读这篇文章,这个人继续谈论如何通过与OOP混合使用面向数据的设计,每个人都能从中受益匪浅.但是,他没有显示任何代码示例.
我搜索了这个,但是找不到任何关于这是什么的真实信息,更不用说任何代码示例了.有人熟悉这个术语并且可以提供一个例子吗?对于别的东西,这可能是一个不同的词吗?
Eri*_*eim 264
首先,不要将此与数据驱动设计混淆.
我对面向数据的设计的理解是它是关于组织数据以进行有效处理.特别是关于缓存未命中等.另一方面,数据驱动设计是关于让数据控制你的许多程序行为(Andrew Keith的回答很好地描述).
假设您的应用程序中有球对象,其颜色,半径,弹性,位置等属性.
面向对象的方法
在OOP中你会像这样描述你的球:
class Ball {
Point position;
Color color;
double radius;
void draw();
};
Run Code Online (Sandbox Code Playgroud)
然后你会创建一个这样的球集合:
vector<Ball> balls;
Run Code Online (Sandbox Code Playgroud)
面向数据的方法
在面向数据的设计中,您更有可能编写如下代码:
class Balls {
vector<Point> position;
vector<Color> color;
vector<double> radius;
void draw();
};
Run Code Online (Sandbox Code Playgroud)
你可以看到,没有一个单位代表一个球了.球对象仅隐含存在.
这可以在性能方面具有许多优点.通常我们希望同时对许多球进行操作.硬件通常需要大量连续的内存块才能高效运行.
其次,您可能会执行仅影响部分球属性的操作.例如,如果您以各种方式组合所有球的颜色,那么您希望缓存仅包含颜色信息.但是,当所有球属性存储在一个单位中时,您也将拉入球的所有其他属性.即使你不需要它们.
缓存使用示例
说一个球,每个球占用64个字节,一个点需要4个字节.缓存槽也需要64个字节.如果我想更新10个球的位置,我必须将10*64 = 640字节的内存拉入缓存并获得10个缓存未命中.但是,如果我可以将球的位置作为单独的单位工作,那将只需要4*10 = 40个字节.这适合一次缓存提取.因此,我们只获得1次缓存未命中以更新所有10个球.这些数字是任意的我假设缓存块更大.
但它说明了内存布局如何具有严重影响缓存命中率和性能.随着CPU和RAM速度之间的差异变宽,这只会增加重要性.
如何布局内存
在我的球示例中,我对问题进行了大量简化,因为通常对于任何普通应用,您可能会同时访问多个变量.例如,位置和半径可能会经常一起使用.那你的结构应该是:
class Body {
Point position;
double radius;
};
class Balls {
vector<Body> bodies;
vector<Color> color;
void draw();
};
Run Code Online (Sandbox Code Playgroud)
您应该这样做的原因是,如果一起使用的数据放在单独的数组中,则存在竞争缓存中相同插槽的风险.因此加载一个会抛弃另一个.
因此,与面向对象编程相比,您最终创建的类与问题的心理模型中的实体无关.由于数据是根据数据使用情况汇总在一起的,因此您不会总是有合理的名称来为数据导向设计提供类.
与关系数据库的关系
面向数据的设计背后的思想与您对关系数据库的看法非常相似.优化关系数据库还可以涉及更高效地使用缓存,尽管在这种情况下,缓存不是CPU缓存放置在内存中的页面.一个好的数据库设计人员也可能会将不经常访问的数据拆分成一个单独的表,而不是创建一个包含大量列的表,而这些列只有少数列使用过.他也可能选择对某些表进行非规范化,以便不必从磁盘上的多个位置访问数据.就像数据导向设计一样,这些选择是通过查看数据访问模式是什么以及性能瓶颈在哪里来做出的.
小智 12
我只是想指出,Noel正在具体谈论我们在游戏开发中面临的一些具体需求.我认为其他正在进行实时软模拟的部门将从中受益,但它不太可能成为一种能够显着改善一般业务应用的技术.此设置用于确保从底层硬件中挤出最后一点性能.
面向数据的设计是一种应用程序逻辑由数据集而不是过程算法构建的设计。例如
程序性方法。
int animation; // this value is the animation index
if(animation == 0)
PerformMoveForward();
else if(animation == 1)
PerformMoveBack();
.... // etc
Run Code Online (Sandbox Code Playgroud)
数据设计方法
typedef struct
{
int Index;
void (*Perform)();
}AnimationIndice;
// build my animation dictionary
AnimationIndice AnimationIndices[] =
{
{ 0,PerformMoveForward }
{ 1,PerformMoveBack }
}
// when its time to run, i use my dictionary to find my logic
int animation; // this value is the animation index
AnimationIndices[animation].Perform();
Run Code Online (Sandbox Code Playgroud)
像这样的数据设计促进了数据的使用来构建应用程序的逻辑。它更容易管理,尤其是在视频游戏中,因为视频游戏可能有数千个基于动画或其他因素的逻辑路径。