CUDA 프로그램의 구조 및 흐름

CUDA 기초 메모리 API

디바이스 메모리 할당 & 해제 & 초기화

디바이스 메모리 할당

/*
ptr: 할단된 디바이스 메모리 공간의 시작 주소를 담을 포인터 변수의 주소
size: 할당할 공간의 크기로 단위는 byte
*/
cudaError_t cudaMalloc(void** ptr, size_t size)

디바이스 메모리 해제

/* 
ptr: 해제할 메모리 공간을 가리키는 포인터 변수
*/
cudaError_t cudaFree(void* ptr)

디바이스 메모리 초기화

/*
ptr: 초기화할 메모리 공간의 시작 주소
value: 초기화할 공간의 각 바이트를 초기화할 값
size: 초기화할 메모리 공간의 크기
*/
cudaError_t cudaMemset(void* ptr, int value, size_t size)

에러 코드 확인

// 해당 함수는 호스트와 디바이스 모두에서 사용할 수 있다
__host__ __device__ const char* cudaGetErrorName(cudaError_t error)

Example

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>

void checkDeviceMemory(void)
{
	size_t free, total;
	cudaMemGetInfo(&free, &total);
	printf("Device memory(free/total) = %lld/%lld bytes\\n", free, total)
}

int main(void)
{
	int *dDataPtr;
	cudaError_t errorCode;

	checkDeviceMemory();
	// dDataPtr에 디바이스 메모리 할당
	errorCode = cudaMalloc(&dDataPtr, sizeof(int) * 1024 * 1024);
	printf("cudaMalloc - %s\\n", cudaGetErrorName(errorCode));
	checkDeviceMemory();
	// dDataPtr을 모두 0으로 초기화
	errorCode = cudaMemset(dDataPtr, 0, sizeof(int)*32);
	printf("cudaMemset - %s\\n", cudaGetErrorName(errorCode));
	// dDataPtr 디바이스 메모리 해제
	errorCode = cudaFree(dDataPtr);
	printf("cudaFree - %s\\n", cudaGetErrorName(errorCode));
	checkDeviceMemory();
}

/* 주의할 점!
- dDataPtr이 가리키는 주소는 디바이스 메모리상의 주소이기에 호스트 코드에서 
	dDataPtr을 통해 디바이스 메모리에 직접 접근할 수 없다.
- cudaMalloc() 함수의 반환값은 cudaError_t 열거형(enumeration)으로
	호출에 성공하면 cudaSuccess(=0)이 반환된다.
- cudaMalloc()을 통해 메모리 공간을 할당받으면 해당 메모리 공간에 남아 있더
	쓰레기값(garbage value)는 그대로 남아있다. 원하는 값으로 초기화 해주어야 한다.

Tip) 호스트 메모리 영역을 사용하는 변수와 디바이스 메모리 영역을 사용하는 변수를
구분하기 위해, 디바이스 메모리 영역을 사용하는 변수의 이름 앞에 디바이스를 뜻하는
d를 붙여주는 것이 일반적이다.
*/

호스트-디바이스 메모리 데이터 복사 API

장치간 데이터 복사

/*
ptr: 복사될 메모리 공간의 시작주소를 담고있는 포인터 변수
src: 복사할 원본 데이터가 들어 있는 메모리 공간의 시작주소를 담고있는 포인터 변수
size: 복사할 데이터의 크기, 단위는 bytes
kind: cudaMemcpyKind 열거형 변수로 데이터 복사의 방향을 설정하는 인자
	cudaMemcpyHostToHost: host -> host
	cudaMemcpyHostToDevice: host -> device
	cudaMemcpyDeviceToHost: device -> host
	cudaMemcpyDeviceToDevice: device -> device
	cudaMemcpyDefault: dst와 src의 포인터 값에 의해 결정 (비명시적이기 때문에 추천x)
*/
cudaError_t cudaMemcpy(void* dst, const void* src, size_t size, enum cudaMemcpyKind kind)