비동기 셰이더는 AMD에서 마케팅을 위해 사용하는 용어인데요. 비동기 컴퓨트 엔진이 정식 명칭이죠.
때문에 국내외에서 NVIDIA의 경우 비동기 컴퓨팅이 제대로 지원되지 않는것 아니냐 라는 의문이 많은 것 같네요.
그래픽카드 사용자에게 있어서 비동기 컴퓨팅이란 용어는 다소 모호하게 느껴질 수 있죠.
우선 DX11과 DX12의 작동방식의 가장 큰 차이점을 알 필요가 있어요.
DX11은 렌더 타겟의 셰이딩에 필요한 연산이 있으면 그때그때 디바이스에 요청하여 사용 가능한데요.
메모리 관리도 필요한 종류와 크기만 요청하면 나머진 드라이버에서 "알아서 잘" 처리하는게 원칙이에요.
그럼 DX12는 뭐가 다른가 하면...
호스트(CPU)와 디바이스(GPU)간 I/O 오버해드를 줄이기 위해 커맨드 큐(Command queue) 에 커맨드 리스트를 최대한 쌓아두고,
ExecuteCommadList() 라는 함수를 호출하면 호스트에서 순차적으로 디바이스에게 커맨드를 날려요.
인터럽트와 아이들 타임을 줄여 디바이스가 좀더 빡세게 동작하도록 만드는거에요.
(순차처리하는데 멀티스레딩이 어떻게 되죠? - 밑에서 설명)
이렇게 하는 이유가 또 멀티스레드를 사용하면서 스레드 세이프하게 커맨드 셰어링 할 수 있는 가장 좋은 방법이기 때문이죠.
![dx11dx12.jpg dx11dx12.jpg](https://img1.daumcdn.net/relay/cafe/original/?fname=http%3A%2F%2Fgigglehd.com%2Fzbxe%2Ffiles%2Fattach%2Fimages%2F256%2F602%2F204%2F014%2F541279fa7571233a6a29deab8a9adbb7.jpg)
(이미지 출처 - http://videogamesandnews.com/phil-spencer-say-directx-12-wont-help-xbox-one/)
DX11의 경우 호스트 명령 전부가 submit(병합)이 되면 하나의 스레드를 이용하여 디바이스에 present(전송) 하는게 보이죠?
반면 DX12의 경우 CPU가 제공하는 스레드 4개를 이용해서, 즉 커맨드리스트 4개를 동시에 익스큐트하는게 가능하네요.
순차처리의 의문점도 풀리는 순간이죠?
네 호스트에서 처리하는 커맨드 리스트는 동시 처리가 가능하지만, 디바이스와 I/O 할때는 동시 처리가 안되서,
큐를 분리한만큼(여기선 스레드만큼) I/O는 순차적으로 발생하게 되는것이죠.
뭐, 그래도 스레드 1개에서 다 처리하는 것 보단 UMD를 나눠서 동시에 처리하고 KMD가 생략되니 조금 빨라졌네요.
그럼 분리된 큐를 어떻게 GPU에서 효율적으로 연산하는가는 드라이버와 GPU의 워크 스케쥴러가 할 일이죠.
DX11는 그럼 내부적으로 커맨드리스트가 1개뿐인데 GPGPU 단위로 병렬처리가 안되는걸까요?
아니에요. 단지 스레드 세이프하게 커맨드리스트 단위로 나눠 워크 스케쥴링을 하면 되요.
엔비디아 DX12 사용 가이드에도 보면 CommadList 를 분할해서 사용하는걸 권장하고 있죠?
https://developer.nvidia.com/dx12-dos-and-donts
맥스웰 아키텍쳐 시절에 나왔던 문서인데도 CommadList 를 분할하는걸 권장하고 있어요.
DX12를 제대로 쓰려면, 그리고 NVIDIA, AMD 상관없이 비동기 병렬 컴퓨팅이 성능을 짜내는 좋은 방법이란 거에요.
AMD에서 동영상 홍보자료까지 만들어 강조하는 부분이기도 한데 (신호등과 기차 영상), 이것 때문에 논란이 있는것 같네요.
![Async_Aces.png Async_Aces.png](https://img1.daumcdn.net/relay/cafe/original/?fname=http%3A%2F%2Fgigglehd.com%2Fzbxe%2Ffiles%2Fattach%2Fimages%2F1115682%2F130%2F202%2F014%2F27c6882b5f4a6bace30d5b9f4d4f72fb.png)
(8개의 하드웨어 ACE를 탑제한 gcn의 모습 출처 - http://wccftech.com/)
그런데 드라이버로 하나 하드웨어로 가속하나를 떠나서,
실제로 AMD 디바이스에서도 커맨드리스트 분할 스케쥴링을 하고 안하고를 테스트 해보면 성능 차이가 정말 많이 쳐줘야 5% 이내에요.
게다가 게임을 현업에서 개발하며 느끼는거지만, 커맨드리스트 분리가 필요한지가 참 의문인게 (불칸도 그렇고)
정말 적용하기가 까다로와요. 멀티스레드 프로그래밍보다 어렵다고 해야되나..
이런쪽으로 쓸만한 예제도 보면, 비슷한 오브젝트의 인스턴스들이 엄청 많이 있거나, 드로우콜이 많은 경우밖에 없고
(드로우콜은 DX11에선 어떻게든 줄이러 쇼한걸 생각하면, 왜 일부러 늘리려는지 이해불가)
게임에서 오브젝트별로, 또는 렌더타겟별로 어떤 커맨드 큐를 다시 만든다는것 자체가 무척 어려운 일이에요.
실제로 이런 커맨드리스트를 제대로 활용하지 않으면 DX11보다도 성능이 안나와요.
DX11가 Managed 라면 DX12는 Native 한 특성을 가지기 때문이죠.
마치 C를 제대로 못짜는 사람은 C#의 GC와 Managed 프레임워크로 코드를 짰을때가 퍼포먼스가 오히려 좋게 나오는것 처럼요.
결론은 하드웨어 ACE, AS 다 좋다는겁니다. 근데 게임에서 fps로 반영되는 결과물은 60fps당 3프레임 이내라는 것이죠.
그렇게 프로그래머 피말려가며 3프레임 더 뽑아냈는데, 결국은 뭐에요. 연산량 50% 향상된 최신 그래픽카드가 나오지 않나요?
GPU에서 정말 중요한건 ACE가 아니에요. GFLOPS죠.
그리고 NVIDIA라고 ACE를 지원 안하는건 아니라는 거에요.
참고 - https://m.reddit.com/r/nvidia/comments/3j5e9b/analysis_async_compute_is_it_true_nvidia_cant_do/
참고 - http://videogamesandnews.com/phil-spencer-say-directx-12-wont-help-xbox-one/
참고 - http://neogaf.com/forum/showpost.php?p=176935407
참고 - https://msdn.microsoft.com/en-us/library/windows/desktop/dn899121(v=vs.85).aspx
참고 - https://www.youtube.com/channel/UCiaX2B8XiXR70jaN7NK-FpA
참고 - https://developer.nvidia.com/dx12-dos-and-donts
참고 - https://megayuchi.wordpress.com/2016/05/19/
참고 - http://www.slideshare.net/dgtman/tips-and-experience-of-dx12-engine-development