Что такое ориентированный на данные дизайн? - PullRequest
134 голосов
/ 29 октября 2009

Я читал эту статью , и этот парень продолжает говорить о том, как каждый может получить большую выгоду от смешивания в ориентированном на данные проектировании с ООП. Однако он не показывает никаких примеров кода.

Я гуглил это и не смог найти никакой реальной информации о том, что это такое, не говоря уже о примерах кода. Кто-нибудь знаком с этим термином и может привести пример? Это может быть другое слово для чего-то еще?

Ответы [ 4 ]

251 голосов
/ 07 января 2010

Прежде всего, не путайте это с дизайном, управляемым данными.

Я понимаю, что Data Oriented Design - это организация ваших данных для эффективной обработки. Особенно в отношении пропусков кэша и т. Д. С другой стороны, Data Driven Design - это то, что позволяет данным контролировать поведение многих ваших программ (очень хорошо описано Эндрю Китом ).

Допустим, в вашем приложении есть шариковые объекты с такими свойствами, как цвет, радиус, упругость, положение и т. Д.

Объектно-ориентированный подход

В ООП вы бы описали свои шары так:

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

  void draw();
};

И тогда вы создадите коллекцию шариков, подобную этой:

vector<Ball> balls;

Ориентированный на данные подход

Однако в Data Oriented Design вы, скорее всего, напишите такой код:

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

  void draw();
};

Как вы можете видеть, больше нет единой единицы, представляющей один Шар. Объекты шара существуют только неявно.

Это может иметь много преимуществ в плане производительности. Обычно мы хотим выполнять операции на нескольких шарах одновременно. Аппаратные средства обычно хотят, чтобы большие непрерывные порции памяти работали эффективно.

Во-вторых, вы можете выполнять операции, которые влияют только на часть свойств шариков. Например. если вы комбинируете цвета всех шаров по-разному, то вы хотите, чтобы ваш кеш содержал только информацию о цвете. Однако, когда все свойства шара сохранены в одной единице, вы также включите все другие свойства шара. Даже если они вам не нужны.

Пример использования кэша

Скажем, каждый мяч занимает 64 байта, а Очко занимает 4 байта. Слот для кэша также занимает, скажем, 64 байта. Если я хочу обновить позицию 10 шаров, я должен вытянуть 10 * 64 = 640 байт памяти в кеш и получить 10 промахов в кеше. Однако, если я могу работать с позициями шаров как с отдельными единицами, это займет всего 4 * 10 = 40 байт. Это помещается в одну выборку кеша. Таким образом, мы получаем только 1 промах кеша, чтобы обновить все 10 шаров. Эти числа произвольны, я предполагаю, что блок кэша больше.

Но это показывает, как компоновка памяти может иметь серьезные последствия для попадания в кэш и, следовательно, на производительность. Это только увеличится в важности, поскольку разница между скоростью процессора и ОЗУ увеличивается.

Как расположить память

В моем примере с мячом я значительно упростил задачу, потому что обычно для любого обычного приложения вы, вероятно, будете обращаться к нескольким переменным вместе. Например. позиция и радиус, вероятно, будут часто использоваться вместе. Тогда ваша структура должна быть:

class Body {
  Point  position;
  double radius;
};

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

  void draw();
};

Причина, по которой вам следует это сделать, заключается в том, что если данные, используемые вместе, помещаются в отдельные массивы, существует риск того, что они будут конкурировать за одни и те же слоты в кеше. Таким образом, загрузка одного выбросит другого.

Таким образом, по сравнению с объектно-ориентированным программированием классы, которые вы в конечном итоге делаете, не связаны с сущностями в вашей ментальной модели проблемы. Поскольку данные объединяются в единое целое на основе использования данных, у вас не всегда будут разумные имена для обозначения классов в Data Oriented Design.

Отношение к реляционным базам данных

Мышление, стоящее за Data Oriented Design, очень похоже на то, как вы думаете о реляционных базах данных. Оптимизация реляционной базы данных также может включать более эффективное использование кэша, хотя в этом случае кэш-память процессора не помещает страницы в память. Хороший разработчик базы данных также, скорее всего, будет разбивать редко используемые данные на отдельные таблицы, а не создавать таблицу с огромным количеством столбцов, в которых когда-либо использовались только некоторые из столбцов. Он может также выбрать денормализацию некоторых таблиц, чтобы к данным не приходилось обращаться из нескольких мест на диске. Как и в случае с Data-Oriented Design, этот выбор делается при рассмотрении шаблонов доступа к данным и узких мест производительности.

14 голосов
/ 23 июня 2015

Майк Актон недавно выступил с публичной речью о Дизайн, ориентированный на данные :

Моя основная сводка такова: если вы хотите повысить производительность, подумайте о потоке данных, найдите слой хранения, который, скорее всего, вам понравится, и оптимизируйте для него трудно. Майк сосредоточен на Кэш L2 отсутствует, потому что он работает в режиме реального времени, но я думаю, что то же самое относится и к базам данных (чтение с диска) и даже к сети (HTTP-запросы). Думаю, это полезный способ системного программирования.

Обратите внимание, что это не освобождает вас от размышлений об алгоритмах и сложности времени, оно просто сосредотачивает ваше внимание на поиске самого дорогого типа операций, на который вы затем должны ориентироваться с помощью своих безумных навыков CS.

12 голосов
/ 23 февраля 2010

Я просто хочу отметить, что Ноэль говорит конкретно о некоторых специфических потребностях, с которыми мы сталкиваемся при разработке игр. Я полагаю, что другие сектора, которые выполняют мягкое моделирование в реальном времени, выиграют от этого, но вряд ли это будет метод, который покажет заметное улучшение для общих бизнес-приложений. Эта настройка предназначена для обеспечения того, чтобы каждый последний бит производительности выдавливался из базового оборудования.

0 голосов
/ 29 октября 2009

Ориентированный на данные проект - это проект, в котором логика приложения состоит из наборов данных, а не процедурных алгоритмов. Например

процедурный подход.

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

Подобные конструкции данных способствуют использованию данных для построения логики приложения. Управлять им проще, особенно в видеоиграх, которые могут иметь тысячи логических путей на основе анимации или какого-либо другого фактора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...