728x90

1. 데이터 지역성 패턴 ( Data Locality Pattern ) 정의

  • CPU 캐시를 최대한 활용할 수 있도록 데이터를 배치해 메모리 접근 속도를 높인다.

 

2. 캐시 라인 ( Cache Line )

캐시 라인

  • RAM으로부터 데이터를 한 바이트라도 가져와야 할 경우, RAM은 ( 보통 64~128바이트 정도의 ) 연속된 메모리를 선택해 캐시에 복사한다. 이런 메모리 덩어리를 캐시 라인이라고 한다.
  • 필요한 데이터가 캐시 라인 안에 들어 있다면 CPU는 RAM보다 훨씬 빠른 캐시로부터 데이터를 가져올 수 있다.

 

3. 캐시 히트 ( Cache Hit ), 캐시 미스 ( Cache Miss )

  • 캐시에서 원하는 데이터를 찾는 것을 캐시 히트
  • 데이터를 찾지 못해 주 메모리에서 데이터를 가져오는 것을 캐시 미스라고 한다. ( 캐시 미스 발생 시 CPU는 멈춘다. )

 

4. 캐시 미스가 발생되는 코드

	while ( !bGameOver )
	{
		// AI를 처리한다.
		for ( int index = 0; index < numEntities; ++index )
			entities[ index ]->GetAI()->Update();

		// 물리를 업데이트한다.
		for ( int index = 0; index < numEntities; ++index )
			entities[ index ]->GetPhysics()->Update();

		// 화면에 그린다.
		for ( int index = 0; index < numEntities; ++index )
			entities[ index ]->GetRender()->Render();
	}
  • 게임 개체가 배열에 포인터로 저장되어 있어, 배열 값에 접근할 때마다 포인터를 따라가면서 캐시 미스가 발생한다.
  • 게임 개체는 컴포넌트를 포인터로 들고 있어서 다시 한번 캐시 미스가 발생한다.

 

5. 캐시 히트를 높히기 위한 코드

	// 컴포넌트 자료형별로 큰 배열 준비
	AIComponent* aiComponents = new AIComponent[ MAX_ENTITIES ];
	PhysicsComponent* physicsComponents = new PhysicsComponent[ MAX_ENTITIES ];
	RenderComponent* renderComponents = new RenderComponent[ MAX_ENTITIES ];

	while ( !bGameOver )
	{
		// AI를 처리한다.
		for ( int index = 0; index < numEntities; ++index )
			aiComponents[ index ].Update();

		// 물리를 업데이트한다.
		for ( int index = 0; index < numEntities; ++index )
			physicsComponents[ index ].Update();

		// 화면에 그린다.
		for ( int index = 0; index < numEntities; ++index )
			renderComponents[ index ].Render();
	}
  • 배열에 컴포넌트 포인터가 아닌, 컴포넌트 객체를 넣어 사용한다.
  • 모든 데이터가 배열 안에 나란히 들어 있기 때문에 게임 루프에서는 객체에 바로 접근할 수 있다.
  • 간접 참조 연산자 ( -> )의 개수를 줄여 포인터를 따라가며 발생하는 캐시 미스를 개선할 수 있다.
반응형

+ Recent posts