2015. 6. 23. 18:59ㆍ프로그래밍/ETC
서론
트리플 버퍼링에 대한 아카데미 동기의 해석을 링크해왔다.
더블 버퍼링도 빡센데 트리플이라니!!!
링크
작성일: June 22, 2015 09:53 AM UTC
원문 작성일: June 26, 2009 12:34 AM EST
작성자: Derek Wilson
번역자: Sungkuk Park
원문 주소: http://www.anandtech.com/show/2794/2
더블 버퍼링(Double Buffering), vsync, 그리고 트리플 버퍼링(Triple Buffering)은 무엇인가?
컴퓨터가 무언가를 모니터로 디스플레이 하기 위해서는, 컴퓨터는 일단 스크린에 뿌릴 그림을 그리고 이 버퍼(buffer)라고 부르는 그림을 모니터로 전송해야 한다. 옛날에는 오직 하나의 버퍼를 사용했으며, 이 버퍼가 그려지고 전송되는 것이 연속적으로 수행되었다. 이러한 방식에는 장점도 있지만, 매우 큰 단점들이 뒤따랐다. 특히, 디스플레이에 그려지는 대상들이 업데이트(updated) 되는 동안 깜빡이는(flicker) 현상이 대표적이다.
컴퓨터가 컨텐츠(contents)로서 임시로 그린 것들이 전송된다.
All illustrations courtesy Laura Wilson.
이처럼 같은 버퍼를 그리는 동안에 불러옴으로 인해 발생하는 문제들을 해결하기 위해, 더블 버퍼링이 등장했다. 더블 버퍼링은 컴퓨터가 “백(back)” 버퍼라고 불리는 버퍼에만 그림을 그리고, 이를 또 다른 버퍼인 “프론트(front)” 버퍼를 통해 스크린으로 전송하는 기법이다.
컴퓨터가 백 버퍼에 그림을 그리고 나면, 해당 프로그램은 버퍼 스왑(swap)이라고 불리는 그리기 동작을 한다. 이 스왑은 실제로는 아무 것도 움직이지 않고, 단지 두 버퍼의 이름만을 교환할 뿐이다. 백 버퍼는 프론트 버퍼가 되고, 프론트 버퍼는 백 버퍼가 된다.
컴퓨터는 백 버퍼에 그리고, 모니터는 프론트로 전송한다..
버퍼 스왑 이후, 소프트웨어는 이 새로운 백 버퍼에 그림을 그리고, 다음 버퍼 스왑이 일어날 때까지 새로운 프론트 버퍼를 스크린으로 전송한다. 이러한 더블 버퍼링은 잘 작동하는데, 몇 가지 문제가 있다.
더블 버퍼링에 있어서, 이 스왑(swap)은 언제든지 일어날 수 있다. 이는 컴퓨터가 데이터를 모니터로 보내는 동안에도 스왑이 일어날 수 있다는 것을 의미한다. 이런 경우가 생기면, 스크린에는 새로운 버퍼에 그려진 내용이 출력된다. 새로운 프론트 버퍼가 이전의 프론트 버퍼와 다르게 되면, 티어링(tearing)이라는 현상이 발생한다. 이 티어링은 높은 프레임레이트의 FPS 게임에서 코너에서 카메라를 최대한 빨리 휙휙 돌리게 되면 발생할 수 있다. 지나치게 빠른 동작 때문에, 매 프레임이 서로 달라지게 되고, 그림이 그려지는 동안에 스왑이 일어날 때 이러한 불일치가 커지면 스왑 동작을 방해할 수 있다.
티어링을 해결하는 가장 일반적인 방법은 모니터가 다른 이미지를 받아들일 준비될 때까지 스왑 버퍼를 기다리는 것이다. 이를 모니터가 전송된 이미지를 모두 그리고 나서 준비가 된 상태에다가 다음 수직 재생 사이클(vertical refresh cycle)이 시작되면, 버퍼 스왑을 수직 재생(Vertical refresh)과 동기화한다(Synchronizing)고 해서 vsync라고 부른다.
이 vsync는 티어링 현상을 해결하는 동시에, 게임 내에 내부 프레임레이트라는 것을 설정하는데, 대개 이 재생률(refresh rate)은 대다수의 LCD 패널에 대해 60Hz에 해당한다. 그리고 이러한 내부 프렘레이트는 게임이 초당 60 프레임으로 실행되지 않는다고 해도 게임의 퍼포먼스를 저하시킬 수 있다. 왜냐하면 동기화 효과로 인한 기술적 딜레이가 발생하기 때문이다. 16.67 ms (60분의 1초)보다 더 약간 긴 모든 프레임들은 퍼포먼스가 거의 반으로 감소할 것이다. 즉, 60 FPS 하에 돌아가야 할 게임의 프레임레이트가 30 FPS로 떨어질 것이다. 그러나 이 경우에 티어링 현상은 해결될 것이고 프레임레이트는 안정적일 것이며, vsync가 적용되지 않은 더블 버퍼링이 가질 수 없는 부드러움이 확보된다.
입력 렉(lag) 또한 vsync를 활성화시켰을 때의 무시할 수 없는 문제에 해당한다. 이는 기술적 딜레이가 발생 시 어떤 것이 실제로 일어나기까지의 시간이 더 걸리는 현상을 발생시키기 때문이다. 결국, 프레임이 그려져 스크린에 디스플레이 될 때, 항상 입력 렉이 발생한다(현재 발생하고 있는 것을 즉각적으로 화면에 그려주는 것은 불가능하다). 그러나, 이러한 입력 렉 문제를 최소화할 트릭이 존재한다.
더블 버퍼링에서 시각적(visual) 문제 해결을 위한 선택지는vsync를 적용하지 않고 티어링을 감수하느냐, 아니면 기술적인 딜레이로 인한 퍼포먼스의 감소와 입력 렉의 증가를 감수하느냐의 문제였다. 그러나, 퀄리티(quality)와 퍼포먼스 중 어떤 것도 포기하지 않고 이 둘을 결합하는 방법이 존재한다. 그 선택지는 트리플 버퍼링이다.
컴퓨터는 모니터가 프론트 버퍼를 전송 받을 때 서로를 오고 갈(bounce) 두 개의 백 버퍼를 가진다..
그 이름에서 알 수 있듯, 트리플 버퍼링은 두 개의 버퍼 대신 세 개의 버퍼를 사용한다. 이 추가적인 버퍼는 컴퓨터가 이 버퍼가 모니터로 보내지는 동안 해당 버퍼를 잠가 둘(lock) 충분한 공간을 제공하면서(티어링 방지), 소프트웨어가 나머지 두 버퍼 사이를 오가며 최대한 빨리 그림을 그릴 수 있도록 해준다. 소프트웨어는 두 개의 백 버퍼 사이를 오가면서, 가능하면 매 재생 시점, 즉 프론트 버퍼가 가장 최신의 완전히 렌더된(rendered) 프레임을 가진 백 버퍼와 스왑되게 된다. 이는 그래픽 카드에서 15 ~ 25 MB의 추가적인 공간을 차지하지만, 보드(board)의 최소 용량이 512 MB인 현재의 그래픽 카드에 있어 이러한 추가 용량은 문제될 것이 없다,
다시 말해, 트리플 버퍼링은 vsync를 비활성화 했을 때와 같은 정도의 퍼포먼스를 얻으면서 vsync가 활성화되어 있을 때의 비주얼 퀄리티(visual quality)와 부드러움을 동시에 확보할 수 있는 것이다.
여기서, 중요하게 언급해야 할 점은, 트리플 버퍼링이 적용된 게임의 “프레임레이트”를 볼 때 실제 “퍼포먼스”의 차이를 볼 수는 없다는 것이다. FRAPS와 같은 프레임 계산 프로그램은 단지 모니터로 전송되는 프론트 버퍼가 스왑되는 수를 측정할 뿐이다. 더블 버퍼링에서, 이러한 스왑은 모니터가 현재 프레임을 받고 그리고 나서, 다음 프레임이 이미 완료되었다면 매 프레임마다 일어난다(이는 바꿔 말하자면, 다음 재생(refresh) 전에는 이미 그려졌다고 하더라도 아무 것도 디스플레이 되지 않는다는 말이다.). 트리플 버퍼링에서, 프론트 버퍼의 스왑은 매 vsync에 한 번씩만 발생한다.
트리플 버퍼링 시, 소프트웨어에서는 게임의 전체 장면들 뒤에서 두 개의 버퍼 위에 끊임없이 그림을 그린다. 이는 프론트 버퍼 스왑이 일어날 때에도, vsync가 적용된 더블 버퍼링과는 달리 기술적 딜레이가 발생하지 않는다는 뜻이다. 또한 vsync가 적용되지 않은 더블 버퍼링과 달리, 완전히 렌더된 프레임이 모니터로 전송되고 나면, 다른 프레임으로 중간에 교체할 필요가 전혀 없다.
마지막으로 언급할 것은, 트리플 버퍼링을 사용했을 때 감수해야 할 문제점이다. 재생 이후 아주 짧은 시간 동안, vsync가 적용되지 않은 더블 버퍼링에서는 탑(top) 프레임에서 티어링 현상이 발생하며, 나머지 프레임에서는 트리플 프레임보다는 더 적은 렉이 발생한다. 그러나, 트리플 버퍼링에서는 그리기 시작한 프레임을 끝까지 그려야 하며, 이로 인한 시간이 더 걸린다. 그러나 이러한 경우에도, 더블 버퍼링과 트리플 버퍼링의 프레임의 일부는 정확히 같을 것이고, 그 결과와 딜레이는 크게 다르지 않을 것이며, 적어도 vsync가 적용된 더블 버퍼링에 수반되는 나중(future) 프레임들에 대한 영향만큼은 크지 않을 것이다. 만약 당신이 이를 vsync 없는 더블 버퍼링의 장점으로 여긴다면, 이는 잠재적인 티어링 현상을 동방한 이점일 것이다.
이제 이 세 가지 방법을 통한 렌터링 예제들을 비교함으로써 이 아이디어를 명료하게 해 보자.
<끝>
'프로그래밍 > ETC' 카테고리의 다른 글
Unity - PHP 연결 (2) | 2015.07.28 |
---|---|
DIB (0) | 2015.07.28 |
자료형 (1) | 2015.07.28 |
FMOD 세팅하기 (0) | 2015.04.24 |
msimg32.lib, GDI (2) | 2015.04.23 |
GetKeyState, GetAsyncKeyState 차이 (0) | 2015.04.15 |
WinApi 정복 5장 (리소스) (0) | 2015.04.14 |