2009-10-29 9 views
106

私はthis articleを読んでいました。この男は、誰もがOOPを使ったデータ指向設計でどのように混合することで大きな利益を得ることができるか話しています。しかし、彼はどんなコードサンプルも表示していません。データ指向設計とは何ですか?

私はこれを検索して、これが何であるかについての実際の情報を見つけることができませんでした。この用語に詳しい人は誰ですか?これは別の言葉でしょうか?

+6

ゲーム開発者の記事は、ブログの形式で簡単に読むことができるようになりました:http://gamesfromwithin.com/data-oriented-design – Edmundito

+28

これまでにグーグルで何かをして、いい目標を絞ったSOの質問を見つけて、実現しましたか何年も前にそれを聞いたのはあなたでしたか?ここで – ryeguy

+0

は、ウェブ – legends2k

答えて

207

まず、これをデータ駆動型デザインと混同しないでください。

私がデータ指向設計を理解することは、効率的な処理のためにデータを整理することであるということです。特に、キャッシュミスなどに関しては、データ駆動型設計はデータ制御に多くのプログラムの振る舞い(非常によく記述されているのはAndrew Keith's answer)です。

はあなたがあなたにこのようなボールを記述するだろうなど、色、半径、弾み、位置などのプロパティ

オブジェクト指向アプローチOOPで

でアプリケーションにボールオブジェクトを持っていると言います

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

    void draw(); 
}; 

そしてあなたは、このようなボールのコレクションを作成します。

をの

データデータ指向設計で指向アプローチ

は、しかし、あなたはこのようなコードを記述する可能性が高くなります。

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

    void draw(); 
}; 

あなたはもう1個のボールを表す単一のユニットが存在しない見ることができるように。ボールオブジェクトは暗黙的にしか存在しません。

これには、多くの利点があります。通常、私たちは同時に多くのボールを操作したいと考えています。通常、ハードウェアは大量の連続したメモリを効率的に動作させることを望んでいます。

第2に、ボールのプロパティの一部にのみ作用する操作を行う場合があります。例えば。すべてのボールの色をさまざまな方法で組み合わせると、キャッシュには色情報のみが含まれます。しかし、すべてのボールのプロパティが1つのユニットに格納されている場合は、ボールの他のすべてのプロパティも取得します。あなたがそれらを必要としなくても。

キャッシュの使用例

は、各ボールが64バイトを占有し、ポイントが4つのバイトを取り、ボールを言います。キャッシュスロットには64バイトも含まれます。私が10ボールの位置を更新したいのであれば、10 * 64 = 640バイトのメモリをキャッシュに入れて10のキャッシュミスをしなければなりません。しかし、ボールの位置を別々の単位として扱えるのであれば、4×10 = 40バイトしかかかりません。それは1つのキャッシュフェッチに収まります。したがって、我々は1つのキャッシュミスを得るだけで、すべての10個のボールを更新します。これらの数値は任意ですが、私はキャッシュブロックが大きいと仮定します。

ただし、メモリレイアウトがどのようにしてエフェクトキャッシュのヒット率が高く、パフォーマンスが向上するかを示しています。これは、CPUとRAMの速度の差が広がるにつれて重要性が増します。私のボールの例では、メモリに

をレイアウトする方法

通常、任意の通常のアプリを使用すると、複数の変数をおそらく一緒にアクセスするので、私は、問題をたくさん簡素化。例えば。位置と半径はおそらく頻繁に一緒に使用されます。次に、あなたの構造は次のようになります。

class Body { 
    Point position; 
    double radius; 
}; 

class Balls { 
    vector<Body> bodies; 
    vector<Color> color; 

    void draw(); 
}; 

あなたがこれを行う必要がある理由は、一緒に使用されるデータは、別々の配列に配置されている場合、彼らはキャッシュ内の同じスロットに対して競合する危険があるということです。したがって、一方を積み重ねると他方を積み重ねます。

オブジェクト指向プログラミングと比較すると、あなたが作成するクラスは、あなたのメンタルモデルのエンティティとは関係しません。データはデータの使用状況に基づいてまとめられているため、データ指向設計でクラスに与えることは必ずしも分かりません。リレーショナルデータベース

データ指向設計の考え方に

関係では、リレーショナルデータベースについてどのように考えるかと非常によく似ています。リレーショナルデータベースを最適化すると、キャッシュをより効率的に使用することもできますが、この場合、キャッシュはCPUキャッシュのメモリにページを置くことではありません。優れたデータベース設計者は、アクセス回数の少ないデータを別のテーブルに分割し、数多くの列が使用されているテーブルを作成するのではなく、また、テーブルの一部を非正規化して、ディスク上の複数の場所からデータにアクセスする必要がないようにすることもできます。データ指向設計の場合と同様に、これらの選択肢は、データアクセスパターンが何であるか、およびパフォーマンスのボトルネックがどこであるかを調べることによって行われます。

+0

ありがとう、あなたはそれをとてもうまく説明しました。 – ryeguy

+2

もよく言った。私は1つだけの質問を持っている。私たちが構造体 'struct balls {vector pos;ベクトル速度;} 'は、速度ベクトルと位置ベクトルの間を行き来するので、実際にキャッシュをスラッシュする各ボールの位置を更新しません(現代のマシンとキャッシュラインがあります。またイラストだけ)? – falstro

+12

かもしれません。しかし、posアレイ全体が一度に引き込まれることはないことを忘れないでください。ただ1つのキャッシュラインと、いくつかのプリフェッチが可能です。速度と同様に。だから、お互いをゴミ箱にするためには、それぞれ対応するposとvectorのチャンクが同じキャッシュラインにマップされなければなりません。これはもちろん起こり得ることです。そのため、一緒に使用される変数を構造体に入れることが推奨されます。だからベロシティとposは1つのベクトルにあり、カラーは別のベクタにあります。 –

0

データ指向設計は、アプリケーションのロジックがプロシージャアルゴリズムではなくデータセットで構築された設計です。例えば、

手続きアプローチ。このような

int animation; // this value is the animation index 

if(animation == 0) 
    PerformMoveForward(); 
else if(animation == 1) 
    PerformMoveBack(); 
.... // etc 

データ設計アプローチ

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(); 

データの設計は、アプリケーションのロジックを構築するために、データの利用を促進します。アニメーションやその他の要因に基づいて何千ものロジックパスを持つ可能性があるビデオゲームでは、特に管理が容易です。

+9

これは実際には正しくありません。データ指向設計とデータ駆動設計を混同しています。私はノエルの記事を読むまで全く同じことをして、全く違うことについて話していたことに気付きました。 –

+9

また、Indiceは単語でもありません。 「索引」と「索引」があり、「索引」を黙認する人もいますが、「索引」は正しいとは限りません。 – Baxissimo

11

私はノエルがゲーム開発で直面している特定のニーズについて具体的に話していることを指摘したいだけです。リアルタイムのソフトシミュレーションを行っている他のセクターにはこのメリットがあると思いますが、一般的なビジネスアプリケーションに顕著な改善が見られる技術とはなりにくいでしょう。この設定は、パフォーマンスの最後のすべてのビットが基盤となるハードウェアから奪い取られることを保証するためのものです。

+0

合意。データ指向設計が重要な他の分野には、高帯域幅デバイス(ネットワークやストレージなど)のハードウェアとファームウェア、大規模科学計算(天気シミュレーション、タンパク質フォールディング)、シグナル処理(例えば、オーディオ、画像、ビデオ)、データ圧縮などが挙げられる。これらは「コンピュータサイエンスとエンジニアリング」に分類され、時にはより典型的なコンピュータサイエンスとは別のメジャーとして提供されています。 – rwong

11

マイク・アクトンは最近Data oriented designに関する公開講演を行いました:

それの私の基本的な概要は次のようになります、あなたはパフォーマンスをしたい場合は、そのデータの流れを考えるあなたとネジする可能性が最も高いストレージ層を見つけ、それを最適化するハード。 Mikeは彼がリアルタイムでやっているのでL2キャッシュミスに焦点を当てていますが、データベース(ディスク読み取り)とWeb(HTTP要求)にも同じことが当てはまります。それはシステムプログラミングを行うのに便利な方法だと私は思う。それはアルゴリズムと時間の複雑さを考えるからあなたを免除しない

注意、それはちょうどあなたが、あなたの怒っCSのスキルを対象としなければならない最も高価な操作タイプを考え出すであなたの注意を焦点を当てています。