왜 스레드 안전성이 Graphics API에 큰 도움이됩니까?


21

Vulkan과 DirectX12는 모두 스레드 안전 방식으로 사용할 수 있다고 주장합니다. 사람들은 그것에 대해 흥분하는 것 같습니다.

이것이 왜 그렇게 큰 특징으로 간주됩니까? 어쨌든 "실제"처리는 별도의 처리 장치에서 메모리 브리지로 처리됩니다.

또한 너무 큰 경우 왜 스레드 안전 그래픽 API가 나오지 않았습니까?


이 문서에서는 훨씬 더 "게이머 집중"입니다하지만 당신에게 약간의 통찰력 ... 줄 수도 pcgamer.com/what-directx-12-means-for-gamers-and-developers
glampert

답변:


13

주요 이점은 그래픽스 API 액세스와 관련된 모든 어려운 문제를 해결하지 않고도 CPU 작업을 여러 스레드로 더 쉽게 나눌 수 있다는 것입니다. 일반적으로 컨텍스트를 현재 상태로 만들거나 (성능에 나쁜 영향을 줄 수 있음) 대기열을 제공하고 단일 스레드에서 그래픽 API를 호출해야합니다. GPU가 실제로 순차적으로 처리하기 때문에 이런 식으로 성능을 얻을 수 있다고 생각하지 않지만 개발자 작업이 훨씬 쉬워집니다.

아마 지금까지 수행되지 않은 이유는 멀티 스레딩이 실제로 분명하지 않은 시간에 directx와 opengl이 생성 되었기 때문입니다. 또한 Khronos 보드는 API를 변경하는 데 매우 보수적입니다. Vulkan에 대한 그들의 견해는 OpenGL 옆에 공존 할 것입니다. 소비자가 점점 더 많은 프로세서에 액세스함에 따라 최근까지는 패럴 리즘이 그렇게 중요해 졌을 것입니다.

편집 : 나는 여러 CPU에서 작업을 수행하여 성능을 얻지 못한다는 것을 의미하지는 않습니다. 텍스처 / 셰이더를 더 빨리 만들기 위해 호출을 여러 스레드로 나누는 것이 유용하지 않습니다. 오히려 더 많은 프로세서가 사용 중이고 GPU가 수행 할 작업에 바쁘기 때문에 성능이 향상됩니다.


1
참고로 OpenGL은 일반적으로 하나의 스레드에서만 작동하므로 그래픽을 많이 사용하는 앱은 하나의 코어를 최대한 활용할 수 있습니다. Vulkan과 같은 것은 다중 스레드가 명령을 대기열로 디스패치 할 수 있도록 허용하므로 다중 스레드에서 많은 그래픽 호출을 수행 할 수 있습니다.
Soapy

9

GPU를위한 프레임을 설정하기 위해 CPU에 많은 작업이 필요하며, 그 작업의 좋은 부분은 그래픽 드라이버 안에 있습니다. DX12 / Vulkan 이전에는 그래픽 디자인 작업이 API 디자인에 의해 단일 스레드로 강제되었습니다.

DX12 / Vulkan은 이러한 제한을 해제하여 프레임 내의 여러 CPU 스레드에서 드라이버 작업을 병렬로 수행 할 수 있기를 바랍니다. 이를 통해 멀티 코어 CPU를보다 효율적으로 사용할 수 있으므로 게임 엔진이 CPU에 종속되지 않고 더 복잡한 장면을 푸시 할 수 있습니다. 그것이 희망입니다. 실제로 실현 될지 여부는 앞으로 몇 년 동안 기다려야 할 것입니다.

좀 더 정교하게 설명하자면 : 게임 엔진 렌더러의 출력은 프레임을 렌더링하는 일련의 작업을 설명하는 DX / GL API 호출 스트림입니다. 그러나 API 호출 스트림과 GPU 하드웨어가 사용하는 실제 이진 명령 버퍼 사이에는 큰 거리가 있습니다. 드라이버는 API 호출을 GPU의 기계 언어로 "컴파일"해야합니다. 이는 간단한 프로세스가 아닙니다. API 개념을 저수준 하드웨어 현실로 변환하고, GPU가 유효하지 않은 상태로 설정되지 않았는지 확인하는 유효성 검사, 메모리 할당 및 데이터 조정, 상태 변경을 추적하여 올바른 하위 수준 명령 등. 그래픽 드라이버는이 모든 것을 담당합니다.

DX11 / GL4 및 이전 API에서이 작업은 일반적으로 단일 드라이버 스레드로 수행됩니다. 여러 스레드에서 API를 호출하더라도 (예를 들어 DX11 지연 명령 목록을 사용하여 수행 할 수 있음) 나중에 드라이버 스레드가 씹을 수 있도록 대기열에 약간의 작업을 추가합니다. 이에 대한 한 가지 큰 이유는 앞에서 언급 한 상태 추적입니다. 많은 하드웨어 수준 GPU 구성 세부 사항에는 현재 그래픽 파이프 라인 상태에 대한 지식이 필요하므로 명령 목록을 병렬로 처리 할 수있는 청크로 분할 할 수있는 좋은 방법이 없습니다. 각 청크는 시작해야하는 상태를 정확히 알아야합니다. 이전 청크가 아직 처리되지 않았음에도 불구하고

그것은 DX12 / Vulkan에서 변경된 큰 것들 중 하나입니다. 우선, 거의 모든 그래픽 파이프 라인 상태를 하나의 객체에 통합하고 명령리스트를 생성 할 때 다른 것 (최소한 DX12) 에 초기 파이프 라인 상태를 제공 해야합니다 . 상태는 하나의 명령 목록에서 다음 명령 목록으로 상속되지 않습니다. 원칙적으로, 이는 드라이버가 컴파일을 시작하기 전에 이전 명령 목록에 대해 아무것도 알 필요가 없으며, 따라서 응용 프로그램이 렌더링을 병렬화 가능한 청크로 분할하여 완전히 컴파일 된 명령 목록을 생성 할 수있게합니다. 서로 연결되어 최소한의 혼란으로 GPU로 전송됩니다.

물론 새 API에는 다른 많은 변경 사항이 있지만 멀티 스레딩에 관한 한 가장 중요한 부분입니다.


5

최신 GPU에는 일반적으로 CPU에서 완전히 선형적인 명령 스트림을 처리하는 단일 프런트 엔드 섹션이 있습니다. 이것이 자연스러운 하드웨어 설계인지 아니면 GPU에 대한 단일 CPU 코어 생성 명령이 있었을 때 단순히 진화했는지 여부는 논란의 여지가 있지만 지금은 현실입니다. 따라서 상태 선형 명령의 단일 선형 스트림을 생성하는 경우 물론 CPU의 단일 스레드에서 해당 스트림을 선형으로 생성하는 것이 좋습니다! 권리?

최신 GPU에는 일반적으로 한 번에 여러 가지 작업을 수행 할 수있는 매우 유연한 통합 백엔드가 있습니다. 일반적으로 GPU는 정점과 픽셀에서 아주 세밀하게 작동합니다. GPU가 한 번의 그리기에서 1024 개의 정점과 두 개의 다른 그리기에서 512 + 512의 정점을 처리하는 것에는 큰 차이가 없습니다.

즉, 한 번의 호출로 GPU에서 많은 수의 정점을 던지는 대신 모델을 섹션으로 나누고, 해당 섹션에서 값싼 거친 컬링을 수행하고, 각 청크를 개별적으로 제출하면 작업량을 줄일 수 있습니다. 컬링 테스트. 당신이 올바른 세분성에서 그것을하면 좋은 속도를 얻을 수 있습니다!

불행하게도, 현재 그래픽스 API 현실에서 드로우 콜은 CPU에서 매우 비쌉니다. 이유에 대한 간단한 설명 : GPU의 상태 변경이 그래픽 API 호출과 직접 일치하지 않을 수 있으므로 많은 그래픽 API 호출이 단순히 드라이버 내부에 일부 상태를 설정하면이 새로운 상태에 의존하는 드로우 호출이 진행됩니다. 마지막 드로우 이후 변경된 것으로 표시된 상태를 GPU의 명령 스트림에 기록한 다음 실제로 드로우를 시작합니다. 이것은 GPU 프론트 엔드 장치를위한 단순하고 평균적인 명령 스트림을 얻기 위해 수행되는 모든 작업입니다.

이것으로 요약 되는 것은 운전자의 오버 헤드에 의해 전적으로 부과되는 드로 콜 예산 이 있다는 것 입니다. (요즘에는 60 FPS 타이틀에 대해 프레임 당 약 5,000 개를 얻을 수 있다고 들었습니다.)이 명령 스트림을 병렬 청크로 구성하여이 비율을 크게 높일 수 있습니다.

VR 지연 시간 개선을위한 비동기 타임 워프와 같은 다른 이유도 있지만 이는 그래픽 바운드 게임 및 기타 드로우 콜이 많은 소프트웨어 (3D 모델링 패키지 등)에 큰 영향을 미칩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.