2013-02-08 2 views
7

cuda의 가상 아키텍처와 실제 아키텍처의 차이점 및 다양한 구성이 프로그램의 성능에 어떻게 영향을 미치는지 이해하려고 시도합니다.cuda의 가상 아키텍처와 실제 아키텍처의 차이

-gencode arch=compute_20,code=sm_20 
-gencode arch=compute_20,code=sm_21 
-gencode arch=compute_21,code=sm_21 
... 

다음 설명은 NVCC 교재 주어,

GPU 컴파일이 중간 표현 PTX ([...])를 통해 수행된다 A의 어셈블리로 간주 될 수있는 가상 GPU 아키텍처. 실제 그래픽 인 프로세서와 달리 이러한 가상 GPU는 응용 프로그램에 제공하는 기능 집합 또는 기능 집합으로 완전히 정의됩니다. 특히 가상 GPU 아키텍처는 (주로) 일반 명령어 세트를 제공하며 PTX 프로그램은 항상 텍스트 형식으로 표시되기 때문에 이진 명령어 인코딩은 문제가되지 않습니다. 따라서 nvcc 컴파일 명령은 항상 가상 중간 아키텍처를 지정하는 구조와 실제 GPU 아키텍처 을 실행하여 실행할 프로세서를 지정하는 두 가지 아키텍처를 사용합니다. 이러한 nvcc 명령이 유효하려면 실제 아키텍처는 가상 아키텍처의 구현 (어딘가 또는 다른 아키텍처)이어야합니다. 이에 대해서는 아래에서 더 자세히 설명합니다. 선택한 가상 아키텍처는 응용 프로그램에 필요한 GPT 기능에 대한 설명입니다. 가장 작은 가상 아키텍처를 사용하면 두 번째 nvcc 스테이지의 실제 아키텍처가 가장 넓은 범위 인 이 여전히 허용됩니다. 반대로 응용 프로그램에서 사용되지 않는 기능을 제공하는 가상 아키텍처를 지정하면 두 번째 nvcc 단계에서 지정할 수있는 가능한 GPU 집합이 불필요하게 제한됩니다.

그러나 성능이 다른 구성에 어떻게 영향을 주는지 (또는 실제 GPU 장치의 선택에만 영향을 미칠 수 있음) 여전히 얻지는 못합니다.

특히

는 가상 GPU 아키텍처는 (크게) 일반적인 명령어 세트를 제공하고, PTX 프로그램이 항상 표시되기 때문에 바이너리 명령어 인코딩이 아닌 문제 : 특히,이 문장은 나에게 가장 혼란 텍스트 형식.

답변

6

NVIDIA CUDA Compiler Driver NVCC 사용자 가이드 섹션 GPU Compilation은 가상 및 실제 아키텍처에 대한 철저한 설명과 빌드 프로세스에서 개념을 사용하는 방법을 제공합니다.

가상 아키텍처는 코드의 대상이되는 기능 세트를 지정합니다. 아래 나열된 표는 가상 아키텍처의 발전을 보여줍니다. 컴파일 할 때 가장 넓은 범위의 실제 아키텍처에서 프로그램을 실행할 수 있도록 충분한 기능 세트가있는 가장 낮은 가상 아키텍처를 지정해야합니다.

compute_10 Basic features 
compute_11 + atomic memory operations on global memory 
compute_12 + atomic memory operations on shared memory 
      + vote instructions 
compute_13 + double precision floating point support 
compute_20 + Fermi support 
compute_30 + Kepler support 

물리적 아키텍처 (사용 설명서)에서

가상 아키텍처 기능 목록은 GPU의 구현을 지정합니다. 이것은 컴파일러가 명령 세트, 명령 대기 시간, 명령 처리량, 자원 크기 등을 컴파일러에 제공하여 컴파일러가 가상 아키텍처를 바이너리 코드로 최적으로 변환 할 수있게한다.

컴파일러에 여러 가상 및 실제 아키텍처 쌍을 지정하고 컴파일러에서 최종 PTX 및 바이너리를 단일 바이너리로 되돌릴 수 있습니다. 런타임시 CUDA 드라이버는 설치된 실제 장치에 가장 적합한 표현을 선택합니다. 바이너리 코드가 fatbinary에서 제공되지 않으면 드라이버는 최상의 PTX 구현을 런타임 JIT 할 수 있습니다.

1

가상 아키텍처는 GPU의 기능을 지정하고 실제 아키텍처는 그 기능을 지정합니다.

나는 구체적인 예를 생각할 수 없다. 카드가있는 코어의 수를 지정하는 가상 GPU 일 수 있기 때문에 실제 코드는 중복성을 위해 더 많은 비트를 가질 수 있습니다 (또는 제조로 인해 더 적은 비트 수) 오류) 및 첫 번째 단계에서 생성 된보다 일반적인 코드 위에 놓일 수있는 실제로 사용중인 코어에 매핑하는 몇 가지 방법이 있습니다.

특정 아키텍처를 대상으로하는 어셈블리 코드와 비슷한 PTX 코드를 생각해 볼 수 있습니다.이 코드는 특정 프로세서 용 컴퓨터 코드로 컴파일 될 수 있습니다. 올바른 종류의 프로세서 용 어셈블리 코드를 목표로하면 일반적으로 더 나은 기계 코드가 생성됩니다.

0

일반적으로 nvidia가 문서로 쓰는 것은 사람들 (나 자신 포함)이 더 혼란스럽게 만듭니다! (단지 나 아마.)

당신은 성능에 관심이 있습니다. 기본적으로 이것이 (아마도)는 아니지만 꼭해야한다고 말하고 있습니다. 기본적으로 GPU 아키텍처는 자연과 같습니다. 그들은 무언가를 실행하고 무언가가 발생합니다. 그런 다음 그들은 그것을 설명하려고합니다. 그리고 나서 그들은 당신에게 그것을 먹이 죠.

은 결국 몇 가지 테스트를 실행하고 어떤 구성이 최상의 결과를 가져다 주는지 확인해야합니다.

가상 아키텍처는 자유롭게 생각하도록 설계되었습니다. 원하는만큼 스레드를 사용하고 모든 스레드와 블록을 사실상 모든 스레드에 할당 할 수 있습니다. 중요하지 않습니다. PTX로 변환되어 장치에서 실행됩니다.

유일한 문제는 장치 (실제 아키텍처)가 지원하지 않기 때문에 단일 블록 당 1024 개가 넘는 스레드를 할당하면 결과가 0이됩니다.

또는 예를 들어 장치가 CUDA 1.2를 지원하면 코드에서 이중 포인팅 변수를 정의 할 수 있지만 간단히 장치가이를 실행할 수 없기 때문에 다시 0으로 표시됩니다.

성능을 높이려면 32 개의 스레드 (예 : 경사)마다 메모리의 단일 위치에 액세스해야한다는 점을 알아야합니다. 그렇지 않으면 액세스가 직렬화되는 식입니다.

지금 쯤 요점을 얻었 으면 좋겠다. 상대적으로 새로운 과학이며 GPU는 정말 정교한 하드웨어 아키텍처이다. 모두가 최선을 다하려고 노력하지만 테스트와 게임이다. CUDA의 실제 아키텍처에 대한 지식이 거의 없습니다. GPU 아키텍처 검색을 제안하고 가상 스레드와 스레드 블록이 실제로 어떻게 구현되는지 살펴보십시오.

3

"가상 아키텍처"코드는 장치에로드되기 전에 저스트 - 인 - 타임 컴파일러에 의해 컴파일됩니다. AFAIK, "물리적 아키텍처"코드를 오프라인으로 구축 할 때 NVCC에서 호출하는 컴파일러와 같은 컴파일러입니다. 따라서 결과 응용 프로그램 성능에 차이가 있는지 여부는 알 수 없습니다.

기본적으로 CUDA 하드웨어의 모든 세대는 이전 세대와 2 진 호환되지 않습니다. ARM 명령어 세트를 사용하는 차세대 인텔 프로세서를 상상해보십시오. 이러한 방식으로 가상 아키텍처는 호환 가능한 하드웨어 용으로 컴파일 할 수있는 CUDA 응용 프로그램의 중간 표현을 제공합니다. 모든 하드웨어 세대는 새로운 명령어 (예 : 새로운 가상 아키텍처가 필요한 이유)를 필요로하는 새로운 기능 (예 : 원자, CUDA 동적 병렬 처리)을 도입합니다.

기본적으로 CDP를 사용하려면 SM 3.5 용으로 컴파일해야합니다. 특정 CUDA 장치 생성을위한 어셈블리 코드를 갖거나이 기능을 제공하는 장치 생성을 위해 장치 어셈블리로 컴파일 될 수있는 PTX 코드로 컴파일 할 수있는 장치 바이너리로 컴파일 할 수 있습니다.