본문 바로가기

Computer Science/Design Pattern

[게임 프로그래밍 패턴] 16. 데이터 지역성 패턴

데이터 지역성 패턴 (Data Locality Pattern)

321 : CPU 캐시를 최대한 활용할 수 있도록 데이터를 배치해 메모리 접근 속도를 높인다.
326 : 자료구조를 잘 만들어서 처리하려는 값이 메모리 내에서 서로 가까이 붙어 있도록 하는 것이 목표다.

데이터 지역성 패턴

데이터 지역성을 높일수록, 즉 데이터를 처리하는 순서대로 연속된 메모리에 둘수록 캐시를 통해서 성능을 향상할 수 있다.

언제 쓸 것인가?

성능 문제가 캐시 미스 때문일 경우 사용한다. 다른 이유 때문이라면 도움되지 않는다.

주의사항

  1. 데이터 지역성 패턴을 위해서는 추상화를 일부 희생해야한다.

최적화에 대한 추가적인 설명들

  1. 많은 프로그래머들은 메모리에서 객체를 복사로 옮기기를 꺼린다. 여러 바이트를 옮기는 것이 포인터를 할당하는 것에 비해서 무겁다고 느끼기 때문이다. 하지만 포인터 추적 비용까지 놓고 보면 직감이 틀릴 수도 있다.
    캐시를 계속 채워놓을 수만 있다면 메모리 복사가 더 쌀 때도 있다.
  2. 컴포넌트의 크기가 커지면 캐시 라인에 들어갈 컴포넌트 개수가 줄어든다. "빈번한 코드"와 "한산한 코드"를 나누고, 한산한 부분은 포인터로 가리키게 하여 필요할 때만 사용한다.

디자인 결정

  1. 다형성은 어떻게 할 것인가?
    1. 사용하지 않는다.
      - 안전하고 쉽다.
      - 더 빠르다.
      - 유연하지 않다.
    2. 종류별로 다른 배열에 넣는다.
      - 객체를 빈틈없이 담을 수 있다.
      - 정적 디스패치를 할 수 있다.
      - 여러 컬렉션을 관리해야 한다.
      - 모든 자료형을 알고 있어야 한다.
    3. 하나의 컬렉션에 포인터를 모아놓는다.
      - 유연하다.
      - 캐시 친화적이지 않다.
  2. 게임 개체는 어떻게 정의할 것인가?
    1. 게임 개체 클래스가 자기 컴포넌트를 포인터로 들고 있을 때
      - 컴포넌트가 연속된 배열에 저장할 수 있다.
      - 개체로부터 개체 컴포넌트를 쉽게 얻을 수 있다.
      - 컴포넌트를 메모리에서 옮기기가 어렵다.
    2. 게임 개체 클래스가 컴포턴트를 ID로 들고 있을 때
      - 더 복잡하다.
      - 더 느리다.
      - 컴포넌트 관리자 같은 것에 접근해야 한다.
    3. 게임 개체가 단순히 ID일 때
      - 개체가 단순해진다.
      - 개체가 비어 있다.
      - 개체 생명주기를 관리하지 않아도 된다.
      - 특정 개체의 컴포넌트를 찾는 게 느릴 수 있다.