주의할 점은 cudaMalloc을 사용할 시, 함수 인자로 이중포인터(void**(&d_data))를 넘겨야 한다.
사람들이 왜 cudaMalloc을 사용할 시 이중포인터를 함수 인자로 넣어야 하는지 궁금해 하는 경우가 많다.
간단하게 이유를 설명 하자면 d_data의 주소(&d_data)는 cpu main 함수 스택에 저장 된다.
cudaMalloc((void**)&d_data, array_byte_size) 에서는 gpu 내에 d_data 값에 동적 메모리 할당을 하고,
이후 gpu 내에서 d_data 값이 새롭게 지정되며, 이 메모리에서 gpu 연산이 되기 때문이다.
그렇지만 d_data의 주소(&d_data)는 cpu main 함수 스택에서 처음과 같이 유지된다.
따라서 이중 포인터를 사용하면, cpu와 gpu에서의 브릿지 역할을 가능하게 할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <time.h>
__global__ void unique_idx_calc_threadIdx(int* input) {
int tid = threadIdx.x;
printf("threadIdx : %d, value : %d \n", tid, input[tid]);
}
__global__ void unique_gid_calculation_3d(int* data)
{
int tid = threadIdx.x + threadIdx.y * blockDim.x + threadIdx.z * blockDim.y * blockDim.x;
int x_offset = blockIdx.x * blockDim.x * blockDim.y * blockDim.z;
int y_offset = blockIdx.y * gridDim.x * blockDim.x * blockDim.y * blockDim.z;
int z_offset = blockIdx.z * gridDim.x * gridDim.y * blockDim.x * blockDim.y * blockDim.z;
int gid = tid + x_offset + y_offset + z_offset;
printf("blockIdx.x : %d, blockIdx.y : %d, blockIdx.z : %d, threadIdx.x : %d, gid : %d, value : %d\n",
blockIdx.x, blockIdx.y, blockIdx.z, threadIdx.x, gid, data[gid]);
}
int main()
{
int array_size = 512;
int array_byte_size = sizeof(int) * array_size;
time_t t;
srand((unsigned int)time(&t));
int* h_data = (int*)malloc(array_byte_size);
for (int i = 0;i < array_size; i++)
{
int num = rand() & 0xff; // 0에서 255까지의 random value를 배열 안에 넣는다.
printf("num value : %d\n", num);
h_data[i] = num;
}
printf("\n \n");
int* d_data;
cudaMalloc((void**)&d_data, array_byte_size);
cudaMemcpy(d_data, h_data, array_byte_size, cudaMemcpyHostToDevice); // Cpu에서 Device(GPU)로 데이터를 보낸다.
dim3 block(2,2,2);
dim3 grid(4,4,4);
unique_gid_calculation_3d <<<grid, block >>>(d_data);
cudaDeviceSynchronize();
cudaDeviceReset();
cudaFree(d_data);
free(h_data);
printf("Success");
return 0;
}
|
cs |
'Cuda' 카테고리의 다른 글
C++ Cuda 시스템 정보, GPU 정보 불러오기 (0) | 2021.05.31 |
---|---|
C++ Cuda CPU와 GPU에서의 연산 속도 비교하기 (0) | 2021.05.30 |
C++ Cuda 메모리 할당에서의 예외 처리 (0) | 2021.05.30 |
C++ Cuda GPU에서의 더하기 연산 (0) | 2021.05.30 |
C++ Cuda 문제 1. Thread index, Block Index, Grid Index 출력하기 (0) | 2021.05.30 |