Qu'est-ce que la conception orientée données?


156

Je lisais cet article , et ce gars continue de parler de la façon dont tout le monde peut grandement bénéficier du mélange de la conception orientée données avec la POO. Il ne montre cependant aucun exemple de code.

J'ai cherché sur Google et je n'ai pas trouvé d'informations réelles sur ce que c'était, sans parler des échantillons de code. Quelqu'un connaît-il ce terme et peut-il donner un exemple? Est-ce peut-être un mot différent pour autre chose?


7
Cet article dans Game developer est maintenant disponible sous forme de blog facile à lire: gamesfromwithin.com/data-oriented-design
Edmundito

58
Avez-vous déjà recherché quelque chose sur Google, trouvé une belle question SO ciblée, puis réalisé que c'était vous qui l'aviez posée il y a des années?
ryeguy

1
Voici un agrégat de contenu DOD sur le Web
legends2k

14
@ryeguy, j'ai eu une question, je l'ai recherchée sur Google, j'ai trouvé une belle question SO, puis j'ai réalisé que j'avais répondu il y a des années.
Michael Deardeuff

4
J'ai googlé quelque chose et trouvé une belle question SO et devinez quoi? Ce n'est pas moi qui ai demandé ni qui a répondu :)
Nadjib Mami

Réponses:


288

Tout d'abord, ne confondez pas cela avec la conception basée sur les données.

Ma compréhension de la conception orientée données est qu'il s'agit d'organiser vos données pour un traitement efficace. Surtout en ce qui concerne les échecs de cache, etc. Data Driven Design d'autre part consiste à laisser les données contrôler une grande partie du comportement de vos programmes (très bien décrit par la réponse d'Andrew Keith ).

Supposons que votre application contienne des objets balle avec des propriétés telles que la couleur, le rayon, le rebond, la position, etc.

Approche orientée objet

En POO, vous décririez des balles comme ceci:

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

  void draw();
};

Et puis vous créeriez une collection de balles comme celle-ci:

vector<Ball> balls;

Approche orientée données

Dans la conception orientée données, cependant, vous êtes plus susceptible d'écrire le code comme ceci:

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

  void draw();
};

Comme vous pouvez le voir, il n'y a plus d'unité unique représentant une seule balle. Les objets Ball n'existent qu'implicitement.

Cela peut présenter de nombreux avantages en termes de performances. Habituellement, nous voulons effectuer des opérations sur plusieurs balles en même temps. Le matériel souhaite généralement que de gros blocs de mémoire continus fonctionnent efficacement.

Deuxièmement, vous pouvez effectuer des opérations qui n'affectent qu'une partie des propriétés d'une balle. Par exemple, si vous combinez les couleurs de toutes les boules de différentes manières, vous voulez que votre cache ne contienne que des informations de couleur. Cependant, lorsque toutes les propriétés de la balle sont stockées dans une seule unité, vous récupérez également toutes les autres propriétés d'une balle. Même si vous n'en avez pas besoin.

Exemple d'utilisation du cache

Disons que chaque boule occupe 64 octets et qu'un point prend 4 octets. Un emplacement de cache prend, disons, 64 octets également. Si je veux mettre à jour la position de 10 balles, je dois insérer 10 * 64 = 640 octets de mémoire dans le cache et obtenir 10 erreurs de cache. Si toutefois je peux travailler les positions des boules comme des unités séparées, cela ne prendra que 4 * 10 = 40 octets. Cela tient dans une extraction de cache. Ainsi, nous n'obtenons qu'un manque de cache pour mettre à jour les 10 balles. Ces nombres sont arbitraires - je suppose qu'un bloc de cache est plus grand.

Mais il illustre comment la disposition de la mémoire peut avoir un effet important sur les accès au cache et donc sur les performances. Cela ne fera qu'augmenter en importance à mesure que la différence entre la vitesse du processeur et de la RAM s'élargit.

Comment organiser la mémoire

Dans mon exemple de balle, j'ai beaucoup simplifié le problème, car généralement, pour toute application normale, vous aurez probablement accès à plusieurs variables ensemble. Par exemple, la position et le rayon seront probablement utilisés ensemble fréquemment. Alors votre structure devrait être:

class Body {
  Point  position;
  double radius;
};

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

  void draw();
};

La raison pour laquelle vous devriez faire cela est que si les données utilisées ensemble sont placées dans des baies séparées, il y a un risque qu'elles soient en concurrence pour les mêmes emplacements dans le cache. Ainsi charger l'un rejettera l'autre.

Donc, par rapport à la programmation orientée objet, les classes que vous finissez par créer ne sont pas liées aux entités de votre modèle mental du problème. Étant donné que les données sont regroupées en fonction de l'utilisation des données, vous n'aurez pas toujours de noms sensés à donner à vos classes dans la conception orientée données.

Relation avec les bases de données relationnelles

La réflexion sur la conception orientée données est très similaire à la façon dont vous pensez aux bases de données relationnelles. L'optimisation d'une base de données relationnelle peut également impliquer une utilisation plus efficace du cache, même si dans ce cas, le cache n'est pas du cache CPU mais des pages en mémoire. Un bon concepteur de base de données divisera probablement les données rarement consultées dans une table séparée plutôt que de créer une table avec un grand nombre de colonnes si seules quelques colonnes sont utilisées. Il peut également choisir de dénormaliser certaines des tables afin que les données ne soient pas accessibles à partir de plusieurs emplacements sur le disque. Tout comme avec la conception orientée données, ces choix sont faits en examinant quels sont les modèles d'accès aux données et où se trouve le goulot d'étranglement des performances.


4
Merci pour cela, vous l'avez très bien expliqué.
ryeguy du

4
bien dit; Je n'ai cependant qu'une seule question. Supposons que nous ayons une structure struct balls {vector<vec3> pos; vector<vec3> velocity;}, que la mise à jour de la position de chaque balle ne ferait pas bouger le cache puisque vous vous déplaceriez entre le vecteur de vitesse et le vecteur de position (oui les machines modernes et les lignes de cache et tout ça, c'est également juste une illustration)?
falstro

14
Ça pourrait. Mais rappelez-vous que tout le tableau pos ne sera pas intégré à la fois. Juste une ligne de cache, et possible une pré-extraction. De même avec la vitesse. Donc, pour qu'ils se détruisent, chaque morceau correspondant de pos et de vecteur doit être mappé sur la même ligne de cache. Cela peut bien sûr arriver, c'est pourquoi la recommandation est de mettre ensemble les variables utilisées dans une structure. Ainsi, par exemple, la vitesse et la position seraient dans un vecteur tandis que la couleur serait dans un autre vecteur.
Erik Engheim

1
@roe Vous devez regrouper les propriétés, auxquelles on accède ensemble. Entre les propriétés, il ne devrait y avoir aucune dépendance. Donc, cette structure serait meilleure struct balls { vector<color> colors; vector<body> bodies; /* contains position and velocity */ }.
danijar

2
@danijar J'ai mis à jour l'explication avec vos suggestions. J'aurais pu en dire beaucoup plus à ce sujet, mais cela deviendra vraiment un article.
Erik Engheim

18

Mike Acton a récemment donné une conférence publique sur la conception orientée données :

Mon résumé de base serait le suivant: si vous voulez des performances, pensez au flux de données, trouvez la couche de stockage la plus susceptible de vous plaire et optimisez-la . Mike se concentre sur les échecs de cache L2, car il fait du temps réel, mais j'imagine que la même chose s'applique aux bases de données (lectures de disque) et même au Web (requêtes HTTP). C'est une façon utile de faire de la programmation de systèmes, je pense.

Notez que cela ne vous dispense pas de penser aux algorithmes et à la complexité temporelle, cela concentre simplement votre attention sur la détermination du type d'opération le plus coûteux que vous devez ensuite cibler avec vos compétences CS folles.


14

Je tiens simplement à souligner que Noel parle spécifiquement de certains des besoins spécifiques auxquels nous sommes confrontés dans le développement de jeux. Je suppose que d'autres secteurs qui font de la simulation douce en temps réel en bénéficieraient, mais il est peu probable que ce soit une technique qui montrera une amélioration notable des applications commerciales générales. Cette configuration permet de garantir que chaque dernier bit de performance est extrait du matériel sous-jacent.


D'accord. Certains autres domaines où la conception orientée données est importante sont: le matériel et le micrologiciel pour les périphériques à large bande passante (par exemple, la mise en réseau ou le stockage); calcul scientifique à grande échelle (par exemple, simulation météorologique, repliement des protéines), traitement du signal (par exemple audio, image, vidéo), compression de données. Celles-ci relèvent de la «science et ingénierie computationnelles» qui est parfois proposée comme une majeure distincte de l'informatique plus typique.
rwong

-3

Une conception orientée données est une conception dans laquelle la logique de l'application est constituée d'ensembles de données, au lieu d'algorithmes procéduraux. Par exemple

approche procédurale.

int animation; // this value is the animation index

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

approche de conception de données

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

Des conceptions de données comme celle-ci favorisent l'utilisation des données pour construire la logique de l'application. Il est plus facile à gérer, en particulier dans les jeux vidéo qui peuvent avoir des milliers de chemins logiques basés sur l'animation ou un autre facteur.


14
Ce n'est en fait pas correct. Vous confondez la conception orientée données avec la conception orientée données. J'ai fait la même chose jusqu'à ce que je lis l'article de Noel et que je réalise qu'il parlait de quelque chose d'entièrement différent.
Erik Engheim du

12
De plus, Indice n'est pas un mot. Il y a des «index» et des «indices» et certains tolèrent même les «index», mais «indice» n'a jamais raison.
Baxissimo
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.