데이터 지향 디자인이란 무엇입니까?


156

나는 이 기사를 읽고 있었고 ,이 사람은 모든 사람들이 데이터 지향 디자인과 OOP를 혼합하여 어떻게 혜택을 볼 수 있는지에 대해 이야기합니다. 그러나 코드 샘플은 표시하지 않습니다.

나는 이것을 봤고 코드 샘플은 말할 것도없이 이것이 무엇인지에 대한 실제 정보를 찾을 수 없었다. 이 용어에 익숙하고 예를 제공 할 수있는 사람이 있습니까? 이것은 다른 단어일까요?


7
게임 개발자의 그 기사는 블로그 형태로 쉽게 읽을에서 사용할 수 있습니다 : gamesfromwithin.com/data-oriented-design
Edmundito

58
당신은 뭔가를 구글 검색하고, 좋은 대상 SO 질문을 찾은 다음, 당신이 몇 년 전에 질문했는지 깨달았습니까?
ryeguy


14
@ryeguy, 나는 질문을했고, 그것을 봤고, 좋은 SO 질문을 찾은 다음 몇 년 전에 대답 했다는 것을 깨달았습니다 .
Michael Deardeuff

4
나는 구글 검색하고 좋은 SO 질문을 발견하고 무엇을 추측? 나에게 물었던 사람은 누구도 아니었다 :)
Nadjib Mami

답변:


287

우선, 이것을 데이터 중심 디자인과 혼동하지 마십시오.

Data Oriented Design에 대한 나의 이해는 효율적인 처리를 위해 데이터를 구성하는 것입니다. 특히 캐시 미스 등과 관련하여 데이터 중심 디자인은 데이터가 많은 프로그램 동작을 제어하도록하는 것입니다 ( Andrew Keith의 답변에 잘 설명되어 있음 ).

색상, 반경, 탄력성, 위치 등과 같은 속성을 가진 응용 프로그램에 공 개체가 있다고 가정 해보십시오.

객체 지향 접근

OOP에서는 다음과 같이 공을 설명합니다.

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

  void draw();
};

그런 다음 다음과 같이 공 모음을 만듭니다.

vector<Ball> balls;

데이터 지향 접근법

그러나 데이터 지향 디자인에서는 다음과 같은 코드를 작성할 가능성이 높습니다.

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

  void draw();
};

보시다시피 더 이상 하나의 볼을 나타내는 단일 유닛이 없습니다. 볼 객체는 암시 적으로 만 존재합니다.

이것은 성능 측면에서 많은 장점을 가질 수 있습니다. 일반적으로 우리는 동시에 많은 볼에서 작업을 수행하려고합니다. 하드웨어는 일반적으로 효율적으로 작동하기 위해 큰 연속 메모리 청크를 원합니다.

둘째, 볼 속성의 일부에만 영향을주는 작업을 수행 할 수 있습니다. 예를 들어 모든 볼의 색상을 다양한 방법으로 결합하면 캐시에 색상 정보 만 포함 시키려고합니다. 그러나 모든 볼 속성이 하나의 유닛에 저장되면 볼의 다른 모든 속성도 가져옵니다. 필요하지 않더라도.

캐시 사용 예

각 볼이 64 바이트를 차지하고 포인트가 4 바이트를 차지한다고 가정 해보십시오. 캐시 슬롯에는 64 바이트도 필요합니다. 10 볼의 위치를 ​​업데이트하려면 10 * 64 = 640 바이트의 메모리를 캐시로 가져와 10 캐시 누락을 가져와야합니다. 그러나 볼의 위치를 ​​별도의 단위로 작업 할 수 있다면 4 * 10 = 40 바이트 만 걸립니다. 하나의 캐시 페치에 적합합니다. 따라서 우리는 10 개의 공을 모두 업데이트하기 위해 1 개의 캐시 미스 만 얻습니다. 이 숫자는 임의적입니다-캐시 블록이 더 크다고 가정합니다.

그러나 메모리 레이아웃이 캐시 적중에 미치는 영향과 성능에 미치는 영향을 보여줍니다. CPU와 RAM 속도의 차이가 커짐에 따라 중요도가 높아집니다.

메모리를 레이아웃하는 방법

내 공 예제에서는 일반적으로 모든 일반 앱의 경우 여러 변수에 함께 액세스 할 수 있기 때문에 문제를 많이 단순화했습니다. 예를 들어 위치와 반경이 자주 사용됩니다. 그런 다음 구조는 다음과 같아야합니다.

class Body {
  Point  position;
  double radius;
};

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

  void draw();
};

이렇게해야하는 이유는 함께 사용 된 데이터가 별도의 어레이에 배치 될 경우 캐시의 동일한 슬롯에 대해 경쟁 할 위험이 있기 때문입니다. 따라서 하나를로드하면 다른 하나를 버릴 것입니다.

따라서 객체 지향 프로그래밍과 비교하여 최종적으로 만드는 클래스는 문제의 정신 모델에있는 엔터티와 관련이 없습니다. 데이터 사용량을 기준으로 데이터가 함께 모이기 때문에 항상 데이터 지향 디자인에서 클래스를 제공 할 수있는 합리적인 이름이있는 것은 아닙니다.

관계형 데이터베이스와의 관계

Data Oriented Design의 기본 개념은 관계형 데이터베이스에 대한 생각과 매우 유사합니다. 이 경우 캐시는 CPU 캐시가 아니라 메모리의 페이지이지만 관계형 데이터베이스 최적화에는 캐시를보다 효율적으로 사용하는 것이 포함될 수도 있습니다. 훌륭한 데이터베이스 디자이너는 열 수가 많은 테이블을 만들지 않고 자주 액세스하지 않는 데이터를 별도의 테이블로 분할 할 수도 있습니다. 또한 디스크의 여러 위치에서 데이터에 액세스 할 필요가 없도록 일부 테이블을 비정규 화하도록 선택할 수도 있습니다. Data Oriented Design과 마찬가지로 이러한 선택은 데이터 액세스 패턴과 성능 병목 현상의 위치를 ​​확인하여 수행됩니다.


4
이것에 감사합니다, 당신은 그것을 잘 설명했습니다.
ryeguy

4
잘했다; 그래도 질문이 하나 있습니다. struct balls {vector<vec3> pos; vector<vec3> velocity;}속도 벡터와 위치 벡터 사이에서 앞뒤로 움직이므로 각 볼의 위치를 ​​업데이트하지 않는다는 구조가 있다고 가정 해 봅시다. 또한 단지 그림)?
falstro

14
그것은 수도. 그러나 전체 pos 배열은 한 번에 당겨지지 않습니다. 하나의 캐시 라인과 일부 프리 페치가 가능합니다. 속도와 마찬가지로. 따라서 서로 포지셔닝하려면 해당하는 pos 및 vector의 각 청크가 동일한 캐시 라인에 매핑되어야합니다. 물론 일어날 수 있기 때문에 함께 사용되는 변수를 구조체에 넣는 것이 좋습니다. 예를 들어 속도와 위치는 한 벡터에 있고 색상은 다른 벡터에 있습니다.
Erik Engheim

1
@roe 함께 액세스되는 속성을 그룹화해야합니다. 속성 사이에는 종속성이 없어야합니다. 따라서이 구조가 더 나을 것 struct balls { vector<color> colors; vector<body> bodies; /* contains position and velocity */ }입니다.
danijar

2
@ danijar 나는 당신의 제안으로 설명을 업데이트했습니다. 나는 이것에 대해 더 많이 말할 수 있었지만 실제로는 기사로 바뀔 것입니다.
Erik Engheim

18

Mike Acton은 최근 데이터 지향 디자인 에 대한 공개 연설을 했습니다.

기본 요약은 다음과 같습니다. 성능을 원한다면 데이터 흐름에 대해 생각하고 나사로 조일 가능성이 가장 높은 스토리지 계층을 찾아 하드에 최적화하십시오 . Mike는 실시간으로 L2 캐시 누락에 중점을두고 있지만 데이터베이스 (디스크 읽기) 및 웹 (HTTP 요청)에도 동일한 사항이 적용된다고 생각합니다. 시스템 프로그래밍을 수행하는 유용한 방법이라고 생각합니다.

알고리즘과 시간 복잡성에 대해 생각하는 것을 막을 수는 없으며 미친 CS 기술로 타겟팅 해야하는 가장 비싼 작업 유형을 파악하는 데주의를 기울입니다.


14

노엘이 우리가 게임 개발에서 직면 한 특정 요구에 대해 구체적으로 이야기하고 있음을 지적하고 싶습니다. 실시간 소프트 시뮬레이션을 수행하는 다른 부문에서이 기능을 활용할 수 있다고 생각하지만 일반적인 비즈니스 응용 프로그램을 눈에 띄게 개선하는 기술은 아닐 것입니다. 이 설정은 모든 마지막 성능 비트가 기본 하드웨어에서 압축되도록하기위한 것입니다.


동의했다. 데이터 지향 설계가 중요한 다른 영역은 다음과 같습니다. 고 대역폭 장치 (예 : 네트워킹 또는 스토리지)를위한 하드웨어 및 펌웨어; 대규모 과학 컴퓨팅 (예 : 날씨 시뮬레이션, 단백질 폴딩), 신호 처리 (예 : 오디오, 이미지, 비디오), 데이터 압축. 이것들은 "전산 과학 및 공학"에 속하며 때로는 더 일반적인 컴퓨터 과학과 별도의 전공으로 제공됩니다.
rwong

-3

데이터 지향 디자인은 응용 프로그램의 논리가 절차 알고리즘 대신 데이터 세트로 구성되는 디자인입니다. 예를 들어

절차 적 접근.

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

이와 같은 데이터 디자인은 응용 프로그램의 논리를 구축하기 위해 데이터 사용을 촉진합니다. 애니메이션이나 다른 요소를 기반으로 수천 개의 논리 경로를 가질 수있는 비디오 게임에서 특히 관리하기가 더 쉽습니다.


14
이것은 실제로 올바르지 않습니다. 데이터 지향 디자인과 데이터 중심 디자인을 혼동하고 있습니다. 나는 노엘의 기사를 읽고 그가 완전히 다른 것에 대해 이야기하고 있다는 것을 깨달을 때까지 똑같은 일을했습니다.
Erik Engheim

12
또한 Indice는 단어가 아닙니다. "index"와 "indices"가 있고 일부는 "indexes"도 있지만 "indice"는 결코 옳지 않습니다.
Baxissimo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.