본인은 유니티 DOTS를 이용해서 대규모 시뮬 게임을 만들고 있음.(4000+개의 유닛)

근데 이 글은 DOTS랑은 큰 상관 없이 최적화에서 아주 잡스러운 기술을 얘기할거임.


미리 말하지만, 내 프로젝트처럼 수백수천개의 연산을 프레임마다 할 때만 쓸만한 잡기술들임.


1. Inversed Variable (분모 변수)

문자 그대로, 변수 b가 있다면, 1/b의 값도 따로 저장하는 것임.

나누기 연산이 곱하기보다 훨씬 무겁기 때문이다.

Unity Physics를 뜯어보면 Mass가 아니라 Inversed Mass를 사용한다.

혹시 나누기를 자주 쓴다, 프레임마다 수백 수천번 쓴다, 하면 분모 변수를 쓰는 것을 추천한다.


근데 만약에 상수로 나눈다면? 일단 DOTS 환경에서 버스트 컴파일은 자동으로 상수 나누기를 상수 곱하기로 바꿔준다.

일단 모노 JIT 컴파일러는 어떻게 하는지는 모르겠다.


2. Random Index (무작위표)

위와 마찬가지로 랜덤 숫자를 만드는 것도 은근 무겁다.

그래서 O(1)인 해시맵에 미리 생성한 랜덤 값들을 넣는다.

나는 이것을 사격 공격의 오차를 넣는 것에 사용한다.

해시맵의 어떤 값을 읽을 지는 키로 정하는데, 이 키는 3번 잡기술이랑 같이 쓴다.


3. 나머지 비트 연산

이것은 2번과 같이 사용하면 좋지만, 창의적인 개발자라면 추가적인 용도를 생각해낼 것이다.

비트 연산 & 로 나머지 (%)를 대체할 수 있으며, 이것은 엄청나게 빠르다.

단, 조건은 2의 x승-1의 값과 &를 해야 한다.

이것은 매우 쉽게 증명할 수 있는데


2의 x승 - 1은 이진법적으로 보면:

1111(15) 111 (7)  11(3)

그래서 이 숫자들과 비트연산 &을 하면, 자연스럽게 이 이진법 숫자의 길이만큼의 숫자만 남게 된다.

이 결과는 나머지 연산과 정확히 일치하다.


이걸 2번과 같이 사용해서, 무작위표의 길이를 16개로 해서 유닛이 사격할 때 이 16개 중에서 무작위로 고르게 하려고 한다면:

(entity index + elapsed time) &15가

(entity index + elapsed time) %16보다 월등히 빠르다.


그리고 IL 코드를 보면 이것은 상수 연산이지만 버스트 컴파일로 자동으로 바뀌지 않는다. 2의 x승에만 쓸 수 있기 때문이다.