CUDA 프로그래밍 환경에서는 PTX assembly를 CUDA 코드에 인라인 시킬 수 있는 방법을 제공한다. 특히 PTX가 포함하고 있는 특수 레지스터 정보를 활용하면, CUDA 애플리케이션이 실행될 때 스레드 블록이 할당된 SM(streaming multiprocessor) 정보를 알 수 있다. 런타임에 스케줄러에 의해 이뤄지는 할당 정보를 파악함으로써, GPU 리소스 점유량에 따른 스케줄링 방식을 간접적으로 판단할 수 있다.
https://docs.nvidia.com/cuda/inline-ptx-assembly/index.html
우선, PTX를 인라인시키는 기본적인 방법을 설명하면 다음과 같다.
어셈블러 지시문(Assembler statement)인 asm( )을 CUDA 코드에 삽입하면, 코드가 PTX로 컴파일될 때 원하는 내용이 함께 삽입되어 PTX 코드로 변환된다. 가장 기본적인 사용문법은 다음과 같다.
asm("template-string" : "constraint"(output) : "constraint"(input));
template-string은 사용하려는 PTX 명령어로서 피연산자와 함께 기술된다. 출력이나 입력이 여러 개 일 경우는 콤마( , )로 분리해서 나타낼 수 있다. constraint은 각 PTX 레지스터 타입을 나타내는데, SM 확인을 위해 사용할 레지스터의 경우는 가장 흔히 사용되는 "r" 타입으로 32bit integer register를 의미한다. 총 5개의 constraint type은 위의 링크에서 확인할 수 있다. 몇 가지 예를 보이면 다음과 같다.
asm("add.s32 %0, %1, %2;" : "=r"(i) : "r"(j) , "r"(k)); 는 add.s32 i, j, k;와 같은 어셈블리어를 삽입하게 된다. 여기서 "="기호는 값을 쓸 레지스터 위치를 의미한다.
asm("add.s32 %0, %0, %1;" : "+r"(i) : "r"(j)); 는 add.s32 i, i, j;를 뜻하게 되는데, "+"기호는 읽을수도 있고, 쓸 수도 있는 레지스터 위치를 의미한다.
asm("mov.u32 %0, %%clock;" : "=r"(x));는 오늘 설명하려는 것과 마찬가지로 특수 레지스터를 사용하는 예로서, %clock로부터 cycle counter를 읽어와서 로드하는 경우의 예이다.
이 포스트에서 설명하려고 하는 내용은, 위에서 언급한 inline PTX assembly의 마지막 예시와 같이 PTX 특수 레지스터 중 하나인 %smid를 이용하여 GPU에 할당된 스레드블록이 실행되고 있는 SM을 확인하는 방법이다. 위의 링크에서 사용한 PTX special register는 세 가지로서 각각의 의미는 다음과 같다.
1) %smid : SM identifier
2) %warpid : Warp identifier
3) %laneid : Lane identifier
스케줄러는 비어있는 SM들을 round-robin 방식으로 하나씩 확인하면서, 가용한 자원이 있을 때 스레드 블록을 할당하는 것으로 알려져 있다. 따라서 위의 링크에서는 기존에 실행된 커널이 없으므로 4개의 스레드 블록이 차례로 할당될 것이고 이 때 실행은 (순차적이지 않고) 동시에 실행되므로 출력 순서는 보기처럼 조금 다를 수 있다.
'CUDA 프로그래밍' 카테고리의 다른 글
SAXPY(Single-precision A-X Plus Y) (0) | 2020.03.03 |
---|---|
MPS란? (0) | 2020.01.29 |
Unified memory를 사용할 때, 공유변수의 동작 예제 (0) | 2020.01.08 |
Rodinia 벤치마크 - 개요 (0) | 2019.10.26 |
CUDA Programming Guide 요약 - 2. Programming Mode (0) | 2019.10.26 |
댓글