DirectX 12 Update Allows CPU and GPU to Access VRAM Simultaneously 라는 기사의 의미

최근에 이런 기사가 떠서 하드웨어 사이트들이 들썩거리는 모양이다.

https://www.tomshardware.com/news/dx12-optimization-cpu-gpu-access-vram-simultaneously

직역하면 ‘GPU메모리에 CPU와 GPU가 동시에 억세스한다.’인데 이렇게 이해하면 안된다.


여기서 동시에 억세스 한다는 말은 프로그래머 입장에서 ‘CPU에서도 GPU메모리를 억세스 할 수 있다’는 의미이다.

  1. 전통적인 PC아키텍처에서는 CPU가 GPU메모리에 직접 접근하지 못한다. 물리적으로 CPU의 어드레스 선과 데이터 선이 GPU메모리와는 연결되어 있지 않다. 오로지 PCI-E버스를 통해서만 통신이 가능하다. 물론 게임기와 모바일 장치들은 통합메모리 시스템이므로 CPU에서 GPU메모리(CPU측 메모리이기도 하다)에 접근할 수 있다.
  2. 이전 세대그래픽 API(D3D7/8/9/10/11/OpenGL 등등)에서는 여러가지 방법으로 CPU에서 GPU메모리에 간접 접근한다. 예를 들면 시스템 메모리를 GPU메모리에 1:1 대응시키는 식으로.
    a. 프로그래머는 시스템 메모리를 업데이트 한다.
    b. 그래픽 API런타임은 백그라운드, 혹은 필요한 때에 시스템 메모리와 GPU메모리를 동기화 시킨다.
    c. 내부적으로는 시스템 메모리의 내용이 프로그래머가 모르는 사이에 GPU메모리로 전송된다.
    d. 일반적으로 Managed Resource라고 하면 이렇게 맵핑된 리소스를 말한다. 이 방식은 생각보다 느리지 않은데 지난 20년 넘게 nvidia등 GPU회사들이 드라이버를 엄청나게 최적화해서 비동기적으로 가장 효율적으로 전송할 수 있는 갖가지 트릭을 구현해 놨기 때문이다.
  3. D3D12는 Managed Resource를 지원하지 않는다. D3D12에서 GPU메모리에 데이터를 써넣으려면 다음과 같은 과정을 거친다.
    a. 명시적으로 gpu메모리에 리소스를 할당한다.
    b. 명시적으로 시스템 메모리에 Upload Buffer를 할당한다.
    c. Upload Buffer에 GPU 메모리에 업데이트할 데이터를 채워 넣는다.
    d. 이것을 명시적으로 할당한 GPU리소스에 전송하도록 D3D API로 요청(CommandList와 CommandQueue를 통해)을 넣어둔다.

    물론 이 작업이 언제 끝날지는 모른다. 이를 추적하는 것은 프로그래머의 몫이다. 여기서 fence를 쳐서 wait할 수도 있고 resource barrier를 쳐서 동기화 시킬 수도 있다.
    어느 쪽이든 코드를 짜는 건 까다롭다. 여기서 상당히 많은 버그가 발생한다. 또한 어떻게 해도 성능이 만족스럽지 않다. 내 경우는 fence를 사용하지 않고 resource barrier만으로 동기화 하는데 어떤 기법을 사용해도 D3D11보다 빨랐던 적은 한번도 없다. 참고로 Metal에서는 Managed Resource를 지원한다. Apple플랫폼이라 덩달아 개똥 취급이 될 수 밖에 없는 Metal의 몇 가지 장점 중 하나이다.
  4. PCI Express의 BAR (Base Address Register)는 CPU측 메모리 어드레스 공간과 주변 기기의 메모리 어드레스 간 맵핑을 제공한다. 이를 사용하면 CPU에서 시스템 메모리에 써넣듯 데이터를 써넣어서 주변기기에 데이터를 전송하는 효과를 볼 수 있다. 물론 CPU가 주변기기의 메모리에 직접 데이터를 써넣는 것이 아니다. 시스템 메모리에 데이터를 써넣으면 이를 PCI Exrpress Bridge가 BAR를 통해 맵핑된 주변기기의 메모리로 전송한다. 여기서의 주소맵핑은 Memory Mapped I/O다. 즉 cpu는 시스템 메모리를 거치지 않고 직접 GPU메모리를 억세스한다. GPU메모리는 빠르지만 PCI버스는 CPU에 비해 상당히 느리므로(대역폭이 아닌 응답성 측면에서) 성능 저하가 있을 수 있다.
  5. D3D에서는 몇 가지 이유로 BAR을 사용하지 않았다고 한다.
    “이전에는 개별 GPU가 PCI 버스를 통해 노출된 프레임 버퍼의 작은 부분만 갖는 것이 일반적이었습니다. D3D는 프레임 버퍼의 I/O 영역이 일반적으로 256MB에 불과하기 때문에 이를 노출하지 않기로 결정했으며 이는 그다지 유용하지 않습니다. 더 큰 문제는 제대로 가상화 가능한 리소스가 아니라는 것입니다. 앱 A가 들어와 256MB를 모두 할당하면 앱 B는 아무 것도 할당할 수 없습니다. 따라서 우리는 그것에 대해 어떤 보장도 제공할 수 없으며, 그 시점에서 앱에 노출하는 것은 나쁜 생각처럼 보였습니다.”
    https://microsoft.github.io/DirectX-Specs/d3d/D3D12GPUUploadHeaps.html
  6. 그랬는데 이제는 Resizable BAR를 지원하는 GPU가 일반화되었기 때문에 이를 사용하여 GPU메모리 주소(사실은 시스템 메모리에 맵핑된)를 프로그래머에게 노출하기로 했다고 한다.
    https://microsoft.github.io/DirectX-Specs/d3d/D3D12GPUUploadHeaps.html
  7. D3D12를 직접 사용하는 프로그래머로서는 꽤 환영할 만한 변화이긴 하다. 물론 이로 인해서 게임이 획기적으로 빨라지거나 하진 않을 것이다. Upload Buffer때문에 불필요한 카피가 많은 건 사실이라 약간 기대를 하고 있긴 한데 일반 유저들이 생각하는 꿈과 희망의 세계와는 관계가 멀다.
  8. 방금 간단하게 테스트 해보니 i7 8700K + RTX3070에선 이 기능을 사용할 수 없다. 웃기게도 D3D Feature Level 11만 지원되는 i3 12100k의 내장 GPU에서는 사용 가능하다. 아직 지원되지 않는 하드웨어들(주로 CPU탓)이 잔뜩 있고 D3D12 Agility SDK 1.7.10 preview에서만 지원되는 기능이므로 게임 개발사들이 코드를 업데이트 하고 일반 게이머들이 이 기능을 체험하려면 꽤 시간이 필요할 것이다.

P.S:
BAR에 대해서는 잘 알지 못하므로 틀린 내용이 있을 수 있습니다. 틀린 내용이 있다면 지적 바랍니다.
CPU에서 BAR를 이용해서 GPU메모리에 억세스할때 시스템 메모리를 거치지 않고 MMIO((Memory Mapped I/O)로 구현됩니다.


DirectX 12 Update Allows CPU and GPU to Access VRAM Simultaneously 라는 기사의 의미”에 대한 답글 8개

  1. Resizable Bar를 활성화시켜야 될 것같아요. 메인보드 세팅에서 가능합니다. 되면 엔비디아 제어판에서 도움말->시스템 정보를 누르면 나오는 대화상자의 세부사항 안에 ‘크기 조절 가능 BAR’가 ‘예’로 뜹니다.(모바일 3060, 데스크탑 3080, 데스크탑 4090) 해당 정보가 없어도 가능한 것으로 보이고요 (모바일 4060에서는 안 보이지만 Vulkan 메모리 프로퍼티 보면 활성화된 것으로 보임)

    좋아요

  2. 그리고 https://www.tomshardware.com/n%E3%85%8Aews/dx12-optimization-cpu-gpu-access-vram-simultaneously 를 보면 해당 옵션은 드라이버 버전에 따라서 지원 여부가 갈린다고 합니다.

    For developers, the feature is already supported by Nvidia, Intel, and AMD drivers. For example, it’s already included in Nvidia’s latest Game Ready and Studio Drivers (version 531.41 or newer) and Intel A-series/Xe GPUs (with driver 31.0.101.4255 or newer). For AMD GPUs, developers must consult their AMD alliance manager to get a supported driver.

    좋아요

    1. 답글이 지워져서 다시
      메인보드에서 Reziable Bar를 활성화해야 합니다.
      활성화가 되면 엔비디아 제어판 메뉴의 도움말 -> 시스템 정보를 누르면 나오는 대화상자에서 ‘크기 조절 가능한 BAR’ 로 활성화가 되었는 지 확인 가능합니다.

      좋아요

  3. 랩톱이 아닌 한 대부분의 현 EFI가 AMI 사의 EFI 펌웨어를 기반으로 하기에 AMIBCP를 이용하여 해당 메뉴가 USER 모드가 아닌 Supervisor 상태로 설정되어 있어 보이지 않는 상태의 메뉴를 임의적으로 활성화시킬 수 있는 방법이 존재합니다.

    아마 Intel CSME가 펌웨어 주소 영역에 대한 읽기 및 쓰기를 방지하고 있어서, 인텔에서 제공하는 플래싱 도구를 사용하여 CSME를 통하여 플래싱이 이루어져야 할 것이기는 한데…

    칩셋 및 프로세서의 PCIe 브릿지 혹은 Root Complex 자체는 Resizable BAR를 지원하는 것으로 알고 있습니다. 그래픽 카드도 아마 해당 기능을 지원할 것이고요.

    Resizable BAR라는 것이 Above 4G Decoding이라 하여, 기존에 32 비트로 여섯 개가 제공되는 BAR을 두 개씩 묶어서 64 비트로 취급하여 4G 이상의 주소 영역에 대하여 PCIe 허브가 메모리 읽기 및 쓰기를 PCIe Read / Write 명령으로 번역하는 것이기 때문에 이론적으로 칩셋이 이러한 주소 디코딩을 지원한다면 가능한 게 맞습니다.

    좋아요

    1. bios업데이트 하면 메뉴가 나올수도 있는데 마지막으로 bios업데이트 했을때 사고가 터졌었기 때문에 bios업데이트 안하고 있습니다. 어차피 어제 새로운 장비로 업그레이드 했기 때문에 굳이 그 장비에서 Resizable BAR를 테스트할 이유는 없네요.

      좋아요

답글 남기기

댓글을 게시하려면 다음의 방법 중 하나를 사용하여 로그인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중