컴퓨터 공학 Computer Engineering/병렬 컴퓨팅 Parallel Computing

[CUDA] 쿠다 프로그램 작성해보기 (.cu 확장자)

킹남지 2021. 9. 18. 20:53
반응형

이 글은 학부 수업을 들으면서 개인적으로 정리한 글입니다. 잘못된 내용이 있다면 댓글로 말씀 부탁드립니다!

 

글에 포함된 코드의 개발 환경은 아래와 같습니다.

- CUDA : CUDA v11.4

- IDE : Visual Studio 2019

- OS : Windows 10

 

CUDA 프로젝트 만들기

최근에는 Visual Studio 내에서 CUDA 프로젝트를 손쉽게 만들 수 있습니다. 

새 프로젝트 만들기를 선택하고 스크롤을 내려보면 아래 그림과 같이 CUDA 프로젝트를 만들 수 있습니다.

(CUDA를 설치해 놓지 않았으면 설치부터 해야합니다.)

 

CUDA 프로젝트 만들기

 

.CU 확장자

위와 같이 쿠다 프로젝트를 만들면 소스 코드의 확장자 명이 .cu 인 것을 확인할 수 있습니다.

 

모든 쿠다 프로그램은 확장자 명으로 .cu 를 사용합니다.

.cu 파일은 .c(.cpp) 파일을 기본으로 쿠다의 일부 기능이 추가된 경우로 생각하면 좋을 것 같습니다.

 

.c(.cpp)파일을 gcc로 컴파일하듯이, .cu 파일은 nvcc 라는 NVIDIA CUDA 컴파일러로 컴파일됩니다.

 

예시

예시 코드와 함께 봅시다. 위에서 언급해듯이 .c(.cpp) 파일을 기본으로 하기에

.cu 파일 내에 아래 코드와 같이 쿠다와 관련 없이, C 또는 C++ 형식의 소스 코드만 있어도 작동합니다.

 

< hello.cu >

#include <stdio.h>

void hello(void) {
	printf("Hello, World!\n");
}

int main(void) {
	hello();

	return 0;
}

하지만 굳이 이럴거면 쿠다 소스 코드 확장자를 사용할 필요가 없겠죠?

 

 

CUDA Source Code

그럼 이제 위의 코드를 바탕으로 쿠다 소스 코드를 한번 작성해보겠습니다.

 

< hello.cu >

#include <stdio.h>

__global__ void hello(void) {
	printf("Hello, CUDA!\n");
}

int main(void) {
	hello <<<1, 1>>> ();
    
	return 0;
}

 

코드의 변화에서 주목해야할 점은

1. __global__ 

2. <<<1, 1>>> 

입니다.

 

1. __global__ 이라는 키워드는 함수를 GPU에서 실행되는 함수로 지정해줍니다. (GPU에서 돌아가도록 명시한다고도 합니다.) 그리고 이렇게 GPU에서 실행되는 함수를 커널(Kernel)이라고 부릅니다.

 

2. <<<M, T>>> 안의 인자 중 앞의 M은 실행될 쓰레드 그룹의 개수를 명시하며, Block이라고 부릅니다. 그리고 인자 중 뒤의 T는 각 block 내에 몇 개의 쓰레드가 실행될 것인지를 명시합니다.

 

위의 예시에서는 hello <<<1, 1>>> (); 로 작성했기에, 1*1 (1 thread, 1 block) 즉, 1개 코어만 사용해 함수가 실행됩니다.

 

활용

그럼 <<<M, T>>> 내의 숫자를 바꿔 실행해보겠습니다. 먼저 T 값을 바꿔보겠습니다.

#include <stdio.h>

__global__ void hello(void) {
	printf("Hello, CUDA! %d \n", threadIdx.x);
}

int main(void) {
	hello <<<1, 10>>> ();

	return 0;
}

위와 같이 코드를  <<<1, 10>>>으로 작성하면

 

10개의 threads가 1 block 실행됩니다. 

이제 우리는 10개의 코어를 사용해 병렬 프로그래밍을 한 것입니다.

 

이때 printf() 문 내에 threadIdx.x 는 block 내에 있는 thread 중 해당 thread의 위치인덱스를 표시합니다.

hello<<<1,10>>>() 와 같은 커널의 경우 0,1,2,3,4,5,6,7,8,9 값 중 하나가 됩니다.

( 이러한 CUDA에 관련된 변수의 내용은 추후에 자세히 알아보도록 하겠습니다. )

 

실행 결과는 아래와 같습니다.

<<<1,10>>> 결과

 

 

그럼 이번에는 <<<M, T>>> 중 M에 해당하는 부분을 바꾸고 실행 결과를 봅시다.

#include <stdio.h>

__global__ void hello(void) {
	printf("Hello, CUDA! %d \n", threadIdx.x);
}

int main(void) {
	hello <<<2, 10>>> ();

	return 0;
}

위와 같이 이번에는 코드를 <<<2, 10>>> 으로 바꿔 작성하면

 

10개의 threads가 2 blocks 실행됩니다. ( 해당 글로벌 함수 hello()를 각 10개의 쓰레드를 갖는 블럭 2개, 총 20개의 쓰레드로 실행시킨 것입니다.)

여기서는 20개의 코어를 사용해 병렬 프로그래밍 했다고 할 수 있습니다.

 

실행 결과는 아래와 같습니다.

<<<2,10>>> 결과

 

이번 글에서는 비주얼 스튜디오 내에서 쿠다 프로젝트를 만들고, 간단한 코드를 작성해 실행해봤습니다.

앞으로 CUDA와 관련된 다양한 글을 써보겠습니다.

 

읽어주셔서 감사합니다. ^^

 

 

 

 

[참고자료]

[1] https://karl6885.github.io/cuda/2018/11/08/NVIDIA-CUDA-tutorial-1/

[2] https://velog.io/@lunarainproject/CUDA-%EA%B8%B0%EC%B4%88

반응형