DDRAW-Surface /D3D-Dynamic Buffer 에서의 Write Combine Memory

20년도 더 전에 DDRAW시절부터 “그래픽카드(그땐 GPU란 말 자체가 없었다)에 쓰는건 생각보다 빠르지만 읽는건 엄청 느리다.”라고 알려져 있었다.

‘PCI버스로 읽어오는게 느리다.’라고만 알고 있었는데 생각해보면 같은 버스로 통신하는건데 쓰는건 빠르고 읽는건 느릴 이유가 있나?실제로 CUDA로 테스트 해보면 GPU로 보내는거나 받아오는거나 성능 차이가 크게 안난다. 따라서 ‘읽는건 느리고 쓰는건 빠르다’라고 하는 사실은 PCI 버스 통신과 무관하다.

DOS시절에야 비디오카드 메모리에 out명령으로 직접 써넣었지만 정상적인 OS가 나온 이후로(Windows 95등) 그렇게 할래야 할수도 없다. DDRAW때부턴 그래픽카드에 맵핑할 메모리를 시스템 메모리에 잡아두고 그 메모리에 일단 써넣은 후 어플리케이션 작동 타이밍 과는 무관하게 비동기적으로 드라이버를 통해 그래픽카드 메모리로 전송했을것이다.

그럼 DDRAW에서 그래픽카드 메모리에 써넣는다고 생각했던 작업들도 사실은 시스템 메모리에 써 넣었다는건데. 같은 시스템 메모리인데 왜 읽는건 느리고 쓰는건 빠른가?

왜냐하면 그 메모리들은 Write Combine속성의 페이지에 올라간 메모리이기 때문이다.
WC 메모리의 경우 아예 캐시되지 않으며 쓰기 작업 수행시 메모리에 직접 쓰는 대신 CPU 내부의 WC버퍼에 먼저 기록된다. 쓰기 명령은 메모리에 실제로 기록될때까지 대기하지 않는다. 따라서 거의 대부분의 쓰기 작업은 메모리에 쓰기 작업을 수행할때까지 약간의 지연시간을 가진다. 대신 쓰기 작업을 하는 cpu측 코드는 빠르게 실행된다.

요약
1. I/O맵핑된 메모리(비디오 재생시 프레임버퍼, DDRAW, D3D등 그래픽 API에서 제공하는 접근 가능한 메모리 등)는 Write Combine속성으로 할당된다.

2. WC메모리는 캐시되지 않는다. 따라서 읽기 작업을 시도하면 실제 메모리에서 즉시 읽어야 하므로 느리다.

3. 써넣기 작업에 대해서는 WC버퍼를 사용하기 때문에 캐시되는 효과가 있다. 따라서 캐시된것만큼 빠르다.20년 넘은 궁금증이 풀렸다.

참고
assembly – WC vs WB memory? Other types of memory on x86_64? – Stack Overflow
24442201.pdf (intel.com)


댓글 남기기