728x90
728x90
1.1 OpenCL ํ๋ก๊ทธ๋จ ๊ตฌ์ฑ
- OpenCL๋ก ํ๋ก๊ทธ๋จ์ ๊ฐ๋ฐํ ๋๋ ๋๋ฐ์ด์ค์์ ๋์ํ๋ ์ปค๋ ํ๋ก๊ทธ๋จ๊ณผ ํธ์คํธ ํ๋ก๊ทธ๋จ์ ๋ฐ๋ก ์์ฑ
- ์ปค๋ ํ๋ก๊ทธ๋จ[์ฝ๋ 3-1] ์ OpenCL C์ธ์ด๋ก ์์ฑ
- ํธ์คํธ ํ๋ก๊ทธ๋จ[์ฝ๋ 3-2] ์ C์ธ์ด๋ก ์์ฑํ๋ OpenCL ๋ฐํ์ API๋ฅผ ์ฌ์ฉ
1.2 ์ปค๋ ํ๋ก๊ทธ๋จ
__kernel void hello(__global char* string)
- OpenCL C์ธ์ด ๋ฌธ๋ฒ์ ๋ง์ถฐ ์์ฑํ๋ค.
- hello() ํจ์์ ์ ์ธ์ ํจ์ ์์์ __kernel์ ์ง์ [C์ธ์ด์ ์ฐจ์ด์ 1]
- ํจ์ ์์์ __kernel ์ hello() ํจ์๊ฐ ๋๋ฐ์ด์ค์์ ๋์ํ๋ฉฐ ํธ์คํธ์์ ํธ์ถํ ์ ์๋ ์ปค๋ ํจ์์์ ์๋ฏธ.
- __kernel ์์์๋ฅผ ์ฌ์ฉํ๋ ์ปค๋ ํจ์๋ ๋ค์ 2๊ฐ์ง OpenCL ๋ฐํ์ API ํจ์๋ฅผ ์ด์ฉํด ํธ์คํธ์์ ํธ์ถ ๊ฐ๋ฅ- ํ์คํฌ ํธ์ถ API ํจ์ : clEnqueueTask()- ๋ฐ์ดํฐ ๋ณ๋ ฌ ํธ์ถ API ํจ์ : clEnqueueNDRangeKernel()- hello() ํจ์๋ ๋ฐ์ดํฐ ๋ณ๋ ฌ์ ์ํ ํจ์๋ ์๋. ํธ์คํธ ํ๋ก๊ทธ๋จ์์ clEnqueueTask ํจ์๋ฅผ ์ด์ฉํด ์ปค๋์ ํธ์ถํจ.
- hello() ํจ์์ ์ฒซ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ string์ ์ฃผ์ ๊ณต๊ฐ ์์์ __global์ ์ง์ [C์ธ์ด์ ์ฐจ์ด์ 2]- OpenCL ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ธ ์ค ๊ธ๋ก๋ฒ ๋ฉ๋ชจ๋ฆฌ์ ์กด์ฌํ๋ค๋ ๊ฒ์ ์๋ฏธํจ.- ์ผ๋ฐ์ ์ผ๋ก ๋๋ฐ์ด์ค ํ๋ก๊ทธ๋จ์ OpenCL ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ธ๋ก ์ ์๋ ๊ธ๋ก๋ฒ ๋ฉ๋ชจ๋ฆฌ, ์ปจ์คํดํธ ๋ฉ๋ชจ๋ฆฌ, ๋ก์ปฌ ๋ฉ๋ชจ๋ฆฌ, ํ๋ผ์ด๋น ๋ฉ๋ชจ๋ฆฌ ์ค ์ด๋ ํ ๊ฐ์ง์ ์ํ๋ค.- ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์ฝ๊ธฐ์ ์ฐ๊ธฐ๊ฐ ๊ฐ๋ฅํ๋ฉฐ, ๊ฐ๊ฐ __global, __constant, __local, __private ์ด๋ผ๋ ์์์๋ฅผ ์ ์- ์ฃผ์ ๊ณต๊ฐ ์์์๋ฅผ ์๋ตํ๋ฉด __private์ผ๋ก ์ง์ ๋๋ค.
01 ์ปค๋๋ด์์ ์ค๋ ๋๊ฐ ๋ช๋ฒ์งธ ์์น์ธ์ง ํ์ธํ๋ ๋ฐฉ๋ฒ
- get_global_size(0) : ๊ฐ๋ก ํฌ๊ธฐ๋ฅผ ๋ฐํํ๋ค.
- get_global_id(1) : ํ์ฌ ์ค๋ ๋์ ์์น๊ฐ ์์์๋ถํฐ ๋ช๋ฒ์งธ์ ์์นํด ์๋์ง๋ฅผ ๋ฐํํ๋ค.
- get_global_id(0) : ํ์ฌ ์ค๋ ๋์ ์์น๊ฐ ์ผ์ชฝ์์๋ถํฐ ๋ช๋ฒ์งธ์ ์์นํด ์๋์ง๋ฅผ ๋ฐํํ๋ค.
1.3 ํธ์คํธ ํ๋ก๊ทธ๋จ
// OpenCL ์ปค๋ ์คํ
ret = clEnqueueTask(command_queue, kernel, 0, NULL, NULL);
- OpenCL C์ธ์ด์ ๋ฌธ๋ฒ์ ๋ฐ๋ผ ๊ฐ๋ฐํ ์ปค๋ ํ๋ก๊ทธ๋จ์ OpenCL ๋ฐํ์ API๋ฅผ ์ด์ฉํด ๊ฐ๋ฐํ ํธ์คํธ ํ๋ก๊ทธ๋จ์ ์ํด ๋๋ฐ์ด์ค์์ ์คํ๋๋ค.
- ์ปค๋ ํจ์ hello()๋ฅผ ํธ์คํธ์์ ํธ์ถํ ๋๋ ๋จ์ง OpenCL ๋ฐํ์ API ํจ์์ ํ๋์ธ clEnqueueTask()๋ฅผ ํธ์ถํ ๋ฟ์ด๋ค. ํ์ง๋ง ์ค์ ๋ก๋ ์ด๋ฅผ ์ํด ์ฌ๋ฌ ๋จ๊ณ์ ์ ์ฐจ๋ฅผ ๊ฑฐ์น๋ค.
- ์ ์ฒด ์ํฌ ํ๋ก์ฐ
- ํ๋ซํผ ์ง์
- ๋๋ฐ์ด์ค ์ ํ
- ์ปจํ ์คํธ ์์ฑ (์ ํ๋ Device๋ฅผ ์ด์ฉํด Context ์์ฑ)
- ์ปค๋งจ๋ ํ ์์ฑ
- ๋ฉ๋ชจ๋ฆฌ ์ค๋ธ์ ํธ ์์ฑ
- ์ปค๋ ํ๋ก๊ทธ๋จ ํ์ผ ์ฝ๊ธฐ
- ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ ์์ฑ
- ์ปค๋ ์ปดํ์ผ
- ์ปค๋ ์ค๋ธ์ ํธ ์์ฑ
- ์ปค๋ ํ๋ผ๋ฏธํฐ ์ค์
- ์ปค๋ ์คํ
- ๋ฉ๋ชจ๋ฆฌ ์ค๋ธ์ ํธ ๋ก๋ (Device๋ก๋ถํฐ ์ฐ์ฐ์ด ์๋ฃ๋ Buffer Data ์ฝ๊ธฐ)
- ์ค๋ธ์ ํธ ํด์
01 ํ๋ซํผ ์ง์
cl_platform_id platform_id = NULL;
...
cl_uint ret_num_platforms;
...
// ํ๋ซํผ, ๋๋ฐ์ด์ค ์ ๋ณด๋ฅผ ์ป์
ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
- OpenCL์ ํ๋ซํผ ๋ชจ๋ธ์ ํ๋์ ํธ์คํธ์ ํธ์คํธ์ ์ฐ๊ฒฐ๋ ํ๋ ์ด์์ ๋๋ฐ์ด์ค๋ก ๊ตฌ์ฑ๋๋ค.
- ๋ฐ๋ผ์ ํธ์คํธ์์ OpenCL์ ์ด์ฉํ ๋๋ ๊ฐ์ ๋จผ์ ํ๋ก๊ทธ๋จ์ด ๋์ํ OpenCL ํ๋ซํผ์ ์ง์ ํด์ผ ํ๋ค.
- clGetPlatformIDs()๋ OpenCL ๋ฐํ์ API์ ์ ์๋ ํจ์์ด๋ฉฐ, ์์คํ ์ ์กด์ฌํ๋ ํ๋ซํผ ID๋ฅผ ์ป๋๋ค.- ์์คํ ์ OpenCL์ด ๋์ํ๋ ํ๋ซํผ(ํ๋์จ์ด)์ด ์กด์ฌํ๋์ง ์ฐพ์๋ณธ ํ,- ๊ฒ์๋ ํ๋ซํผ์ด ์์ ๋ cl_platform_id ํ์ ํ๋ผ๋ฏธํฐ์ธ platform_id์ ํ๋ซํผ ID๋ฅผ ๋ฐํํ๋ค.- ์ดํ ํธ์คํธ ํ๋ก๊ทธ๋จ์ platform_id๋ฅผ ์ง์ ํด ํด๋น ํ๋ซํผ์ ์ด์ฉํ ์ ์๋ค.
- ์ฒซ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ ํธ์คํธ์ ์กด์ฌํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ํ๋ ํ๋ซํผ ์์ด๋ฉฐ ๋ณดํต 1์ ์ง์ ํ๋ค.
- ์ธ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ num_pltform์๋ ์์คํ ์์ ์ค์ ๋ก ์ด์ฉ ๊ฐ๋ฅํ OpenCL ํ๋ซํผ ์๋ฅผ ๋ฐํํ๋ค.
[์ฐธ๊ณ ] 01-1 terasic hello example ์์๋ ์๋์ ๊ฐ์ด ํ๋ซํผ ์ง์
static cl_platform_id platform = NULL;
...
// Get the OpenCL platform.
platform = findPlatform("Altera");
if (platform == NULL) {
printf("ERROR: Unable to find Altera OpenCL platform.\n");
return false;
}
[์ฐธ๊ณ ] 01-2 ํ๋ก๋ฆฐ ๋ธ๋ก๊ทธ ์์
// get all platforms
clGetPlatformIDs(0, NULL, &platformCount);
platforms = (cl_platform_id*)malloc(sizeof(cl_platform_id) * platformCount);
clGetPlatformIDs(platformCount, platforms, NULL);
- platform์ด๋ opencl ์๋น์ค๋ฅผ ์ ๊ณตํ ์ ์๋ ํ๊ฒฝ์ ๋งํ๋ค.
- ํ์ฌ ์ปดํจํฐ์ ์ผ๋ง๋ ๋ง์ ํ๋ซํผ์ด ์๋์ง๋ฅผ ๋จผ์ ์์์์ผ ํ๋ค.- clGetPlatformIDs()๋ฅผ ์ด์ฉํด ํ๋ซํผ์ ๊ฐ์๋ฅผ platformCount์ ๋จผ์ ๋ฐ์์จ๋ค.
- ์ดํ ํ๋ซํผ์ ๊ฐ์๋งํผ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ๊ณ ํ๋ซํผ์ ์ป์ด์ค๊ฒ ๋๋ค.- platform ๋ณ์ ๊ณต๊ฐ์ ํ ๋นํ๊ณ , clGetPlatformIDs()๋ฅผ ํตํด ํ๋ซํผ์ ๋ฐ์์จ๋ค.
02 ๋๋ฐ์ด์ค ์ ํ
cl_device_id device_id = NULL;
...
cl_uint ret_num_devices;
...
// ํ๋ซํผ, ๋๋ฐ์ด์ค ์ ๋ณด๋ฅผ ์ป์
ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &device_id, &ret_num_devices);
- clGetDeviceIDs() ์ญ์ OpenCL ๋ฐํ์ API์ ์ ์๋ ํจ์์ด๋ฉฐ, ํ๋ซํผ์์ ์ด์ฉ ๊ฐ๋ฅํ ๋๋ฐ์ด์ค๋ฅผ ์ป๋๋ค.
- ์ฒซ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์๋ ๋๋ฐ์ด์ค๋ฅผ ์ ํํ๋ ค๋ ํ๋ซํผ์ ์ง์ .
- ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์๋ ๋๋ฐ์ด์ค์ ์ข ๋ฅ๋ฅผ ์ง์ . ํด๋น ์์ ๋ ํ๋ซํผ์ด ์ ๊ณตํ๋ ํ์ค ๋๋ฐ์ด์ค๋ฅผ ๋ํ๋ด๋ CL_DEVICE_TYPE_DEFAULT ๋ฅผ ์ง์
- ์ธ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์๋ ์ป์ด์ผ ํ ๋๋ฐ์ด์ค์ ์๋ฅผ ์ง์ .
- ๋ค ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์๋ device_id์ ์ ์ฅ๋ ๋๋ฐ์ด์ค๋ฅผ ํธ์คํธ ํ๋ก๊ทธ๋จ์์ ์ด์ฉํ๊ธฐ ์ํ cl_device_id ํ์ ๋๋ฐ์ด์ค ํธ๋ค๋ก ๋ฐํํ๋ค.
- ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์์ ์ง์ ํ ๋๋ฐ์ด์ค๊ฐ ํ๋ซํผ์ ์กด์ฌํ์ง ์์ ๋๋ ๋ค์ฏ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ num_devices์ 0์ ๋ฐํํ๋ค.
[์ฐธ๊ณ ] 02-1 terasic hello example ์์๋ ์๋์ ๊ฐ์ด ๋๋ฐ์ด์ค ์ ํ
static cl_device_id device = NULL;
...
// Query the available OpenCL devices.
scoped_array<cl_device_id> devices;
cl_uint num_devices;
devices.reset(getDevices(platform,CL_DEVICE_TYPE_ALL, &num_devices));
// We'll just use the first device.
device = devices[0];
[์ฐธ๊ณ ] 02-2 ํ๋ก๋ฆฐ ๋ธ๋ก๊ทธ ์์
// get all devices
clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 0, NULL, &deviceCount);
devices = (cl_device_id*)malloc(sizeof(cl_device_id) * deviceCount);
clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, deviceCount, device, NULL);
- ๋๋ฐ์ด์ค๋ ๊ณ์ฐ์ ์ํํ ์ ์๋ ์ ๋์ ์งํฉ์ด๋ค.
- GPU๋ก ์ค๋ช ํ์๋ฉด GPU๋ด์ ์๋ง์ ์ฝ์ด๋ค์ ์งํฉ์ด๋ผ๊ณ ๋น์ ํ ์ ์๋ค.
- ํ๋ซํผ ๋ด์ ๋๋ฐ์ด์ค๋ฅผ ์ฐพ์ ์ค์ ๋ก ์ฐ์ฐ์ ์งํํ๊ฒ ๋๋ฉฐ platform์ ๋ฐ์์ค๋ ๊ณผ์ ๊ณผ ๋์ผํ๋ค.
03 ์ปจํ
์คํธ ์์ฑ
cl_context context = NULL;
...
// OpenCL ์ปจํ
์คํธ ์์ฑ
context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &ret);
- ์ด์ฉํ๋ ค๋ ๋๋ฐ์ด์ค ํธ๋ค์ ์ป์๋ค๋ฉด ๋ค์์๋ OpenCL ์คํ ํ๊ฒฝ์ด ๋ OpenCL ์ปจํ ์คํธ๋ฅผ ์์ฑํด์ผ ํ๋ค. clCreateContext()๋ ์ปจํ ์คํธ๋ฅผ ์์ฑํ๊ธฐ ์ํ ํจ์์ด๋ค.
- ๋ณดํต ์ปจํ ์คํธ๋ฅผ ์์ฑํ ๋๋ ์ปค๋์ ์คํํ ๋๋ฐ์ด์ค๋ฅผ ๋ฐ๋์ ํ๋ ์ด์ ์ง์ ํด์ผ ํ๋ค.- ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์๋ ์ด์ฉํ ๋๋ฐ์ด์ค์ ์๋ฅผ- ์ธ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์๋ ์ด์ฉํ ๋๋ฐ์ด์ค์ ํด๋น๋๋ ๋๋ฐ์ด์ค ํธ๋ค์ ๋ฆฌ์คํธ๋ฅผ ์ง์ .
- ์ดํ์ ์์ฑ๋๋ ๊ฐ์ข OpenCL ์ค๋ธ์ ํธ๋ ๋ชจ๋ ์ฌ๊ธฐ์ ์ง์ ํ OpenCL์ ์ปจํ ์คํธ์ ์ํ๊ฒ ๋๋ค. ๊ฐ์ ์ปจํ ์คํธ ์์ ์ค๋ธ์ ํธ๋ฅผ ํตํด์ ๊ฐ ๋๋ฐ์ด์ค๋ฅผ ์ ์ดํ๋ค.
- ์ฆ, ์ปจํ ์คํธ๋ ํ๋ ์ด์์ ์ฐ์ฐ ๋๋ฐ์ด์ค๋ฅผ ์ด์ฉํ ์ ์๋ ๊ฐ์์ ์ปดํจํฐ๋ผ๊ณ ์๊ฐํ๋ฉด ์ฝ๋ค.
[์ฐธ๊ณ ] 03-1 terasic hello example ์์๋ ์๋์ ๊ฐ์ด ์ปจํ
์คํธ ์์ฑ
static cl_context context = NULL;
...
// Create the context.
context = clCreateContext(NULL, 1, &device, NULL, NULL, &status);
checkError(status, "Failed to create context");
[์ฐธ๊ณ ] 03-2 ํ๋ก๋ฆฐ ๋ธ๋ก๊ทธ ์์
// create context
context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL);
- CL ์ปค๋์ด ์คํ๋๋ ํ๊ฒฝ์ผ๋ก, ๋๊ธฐํ์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๊ฐ ์ ์๋๋ค.
- OpenCL๋๋ฐ์ด์ค์์ ์คํํ OpenCLํจ์๋ค์ ํฌํจํ๊ณ ์๋ค.
- clCreateContext()ํจ์๋ฅผ ์ด์ฉํด ์์ฑํ๋ค.
04 ์ปค๋งจ๋ ํ ์์ฑ
cl_command_queue command_queue = NULL;
...
// ์ปค๋งจ๋ ํ ์์ฑ
command_queue = clCreateCommandQueue(context, device_id, 0, &ret);
- ๋๋ฐ์ด์ค๋ฅผ ์ ์ดํ๊ธฐ ์ํ ์ค๋น ๊ณผ์
- OpenCL์์๋ ํธ์คํธ๊ฐ ๋๋ฐ์ด์ค์๊ฒ ๋ฌด์ธ๊ฐ๋ฅผ ์ง์(์ปค๋ ์คํ ๋ช ๋ น, ํน์ ํธ์คํธ~๋๋ฐ์ด์ค ์ฌ์ด์ ๋ฉ๋ชจ๋ฆฌ ์ ์ก ๋ช ๋ น)ํ๋ ค๋ฉด ์ปค๋งจ๋ ํ ์ค๋ธ์ ํธ command_queue๋ฅผ ํตํ๋ค.
- ๊ฐ๊ฐ์ ๋๋ฐ์ด์ค์๋ ๋ฐ๋์ ํ๋ ์ด์์ ์ปค๋งจ๋ ํ ์ค๋ธ์ ํธ๋ฅผ ์์ฑํด์ผ ํ๋ค.
- ํจ์๋ cl_command_queue ํ์ ์ปค๋งจ๋ ํ ํธ๋ค์ ๋ฐํํ๋ฉฐ ์ดํ ์ปค๋์ ์คํํ๊ฑฐ๋ ํธ์คํธ~๋๋ฐ์ด์ค ์ฌ์ด์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์กํ๋ ค๋ฉด ์ด ์ปค๋งจ๋ ํ ํธ๋ค์ ์ง์ ํ๋ค.
- clCreateCommandQueue()๋ ์ปค๋งจ๋ ํ๋ฅผ ์์ฑํ๊ธฐ ์ํ ํจ์์ด๋ค.- context : ์ปค๋งจ๋ ํ๊ฐ ์์๋ ์ปจํ ์คํธ- device_id : ์ปค๋งจ๋ ํ์ ๋ช ๋ น์ ์คํํ ๋๋ฐ์ด์ค๋ฅผ ์ง์
[์ฐธ๊ณ ] 04-1 terasic hello example ์์๋ ์๋์ ๊ฐ์ด ์ปค๋งจ๋ ํ ์์ฑ
static cl_command_queue queue = NULL;
...
// Create the command queue.
queue = clCreateCommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE, &status);
checkError(status, "Failed to create command queue");
[์ฐธ๊ณ ] 04-2 ํ๋ก๋ฆฐ ๋ธ๋ก๊ทธ ์์
// create command queue
queue = clCreateCommandQueue(context, device, 0, NULL);
- ํธ์คํธ์์ ๋๋ฐ์ด์ค ๋ณ๋ก ์์ฑ๋๋ ๊ฒ์ผ๋ก ํ๋์ ๋๋ฐ์ด์ค์์ ์ฌ๋ฌ๊ฐ์ ์ปค๋งจ๋ ํ๊ฐ ์ฐ๊ฒฐ ๊ฐ๋ฅํ๋ค.
- ์ปค๋งจ๋ ํ๋ฅผ ์ด์ฉํด ์ปค๋์ ์คํํ๊ณ ๋ฉ๋ชจ๋ฆฌ์ ๋งคํ, ์ธ๋งคํ, ๋๊ธฐํ ๋ฑ์ ํ ์ ์๋ค.
05 ๋ฉ๋ชจ๋ฆฌ ์ค๋ธ์ ํธ ์์ฑ
cl_mem memobj = NULL;
...
// ๋ฉ๋ชจ๋ฆฌ ๋ฒํผ ์์ฑ
memobj = clCreateBuffer(context, CL_MEM_READ_WRITE, MEM_SIZE * sizeof(char), NULL, &ret);
- ๋๋ฐ์ด์ค์์ ์ปค๋์ด ๋์ํ ๋ ์ปค๋์ ์ฒ๋ฆฌ ๋์์ธ ๋ฐฐ์ด ๋ฑ์ ๋ฐ์ดํฐ๋ ๋ชจ๋ ๋๋ฐ์ด์ค ๋ฉ๋ชจ๋ฆฌ์ ๋ฏธ๋ฆฌ ์ค๋น๋์ด์ผ ํ๋ฉฐ, ๋๋ฐ์ด์ค ๋ฉ๋ชจ๋ฆฌ์ ์ฒ๋ฆฌํ ๋ฐ์ดํฐ๋ฅผ ์ค๋นํ๋ ๊ฒ์ ํธ์คํธ์ ์ญํ ์ด๋ค.
- ์ปค๋ ์์ฒด๋ ๋๋ฐ์ด์ค์ ์ธ๋ถ์ ์๋ ์ ์ฅ์ฅ์น๋ ๋คํธ์ํฌ๋ก๋ถํฐ ๋๋ฐ์ด์ค ๋ฉ๋ชจ๋ฆฌ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค. ๋ฐ๋ผ์ ํธ์คํธ๊ฐ ๋๋ฐ์ด์ค ๋ฉ๋ชจ๋ฆฌ์ ๋ฐ์ดํฐ๋ฅผ ์ค๋นํ ๋๋ ๋ฉ๋ชจ๋ฆฌ ์ค๋ธ์ ํธ๋ฅผ ์์ฑํด์ผ ๋๋ฐ์ด์ค ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ ์ ์๋ค.
- clCreateBuffer()๋ ๋๋ฐ์ด์ค ์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ๋ณดํ๊ธฐ ์ํ ํจ์์ด๋ค. ์ฌ๊ธฐ์ ํ๋ณด๋ ๋ฉ๋ชจ๋ฆฌ๋ ๋ฉ๋ชจ๋ฆฌ ์ค๋ธ์ ํธ memobj๋ฅผ ํตํด ํธ์คํธ์์ ์ฐธ์กฐํ ์ ์๋ค.- context : ๋ฉ๋ชจ๋ฆฌ ์ค๋ธ์ ํธ๊ฐ ์์๋ ์ปจํ ์คํธ๋ฅผ ์ง์ - CL_MEM_READ_WRITE : ๋ฉ๋ชจ๋ฆฌ ์์ฑ, ์ปค๋์ด ๋๋ฐ์ด์ค ์์ ํ๋ณดํ ๋ฉ๋ชจ๋ฆฌ ์์ ๋ฐ์ดํฐ ์ฝ๊ณ ์ฐ๊ธฐ ๊ฐ๋ฅ- MEM_SIZE * sizeof(char) : ํ๋ณดํ ๋ฉ๋ชจ๋ฆฌ ํฌ๊ธฐ๋ฅผ ์ง์
[์ฐธ๊ณ ] terasic example ์ค hello๋ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉํ์ง ์๊ณ , vector add๋ ์๋์ ๊ฐ์ด ๋ฉ๋ชจ๋ฆฌ ์ค๋ธ์ ํฐ ์์ฑ
scoped_array<cl_mem> input_a_buf; // num_devices elements
scoped_array<cl_mem> input_b_buf; // num_devices elements
scoped_array<cl_mem> output_buf; // num_devices elements
...
// Input buffers.
input_a_buf[i] = clCreateBuffer(context, CL_MEM_READ_ONLY, n_per_device[i] * sizeof(float), NULL, &status);
checkError(status, "Failed to create buffer for input A");
input_b_buf[i] = clCreateBuffer(context, CL_MEM_READ_ONLY, n_per_device[i] * sizeof(float), NULL, &status);
checkError(status, "Failed to create buffer for input B");
// Output buffer.
output_buf[i] = clCreateBuffer(context, CL_MEM_WRITE_ONLY, n_per_device[i] * sizeof(float), NULL, &status);
checkError(status, "Failed to create buffer for output");
06 ์ปค๋ ํ๋ก๊ทธ๋จ ํ์ผ ์ฝ๊ธฐ
FILE *fp;
char fileName[] = "./hello.cl";
char *source_str;
size_t source_size;
// ์ปค๋์ ํฌํจํ ์์ค ์ฝ๋๋ฅผ ๋ก๋
fp = fopen(fileName, "r");
if (!fp)
{
fprintf(stderr, "Failed to load kernel.\n");
exit(1);
}
source_str = (char*)malloc(MAX_SOURCE_SIZE);
source_size = fread(source_str, 1, MAX_SOURCE_SIZE, fp);
fclose(fp);
- ๋๋ฐ์ด์ค์์ ์ปค๋์ ์คํํ๋ ค๋ฉด ๋จผ์ ์ปค๋ ํ๋ก๊ทธ๋จ์ ์ฝ์ด๋ค์ผ ํ์๊ฐ ์์ผ๋ฉฐ ์ด ์์ ์ ํธ์คํธ ํ๋ก๊ทธ๋จ์์ ์ด๋ฃจ์ด์ง๋ค.
- ์ฌ๊ธฐ์ ์ปค๋ ํ๋ก๊ทธ๋จ์ OpenCL ์ปดํ์ผ๋ฌ๋ก ๋ฏธ๋ฆฌ ์ปดํ์ผ๋ ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ ํน์ ์ปดํ์ผํ๊ธฐ ์ ์ ์์ค ์ฝ๋ ์ผ ์๋ ์๋ค.
- ์ปค๋ ํ์ผ์ ์ฝ์ ๋๋ OpenCL ๋ฐํ์ API๋ฅผ ์ด์ฉํ์ง ์๋๋ค.
- fopen๊ณผ fread๋ฅผ ํตํด OpenCL C์ธ์ด์ ์์ค ์ฝ๋๋ฅผ ์ปค๋ ํ๋ก๊ทธ๋จ์ผ๋ก ์ฝ์ด๋ค์ธ๋ค.
- ์ปค๋ ํ๋ก๊ทธ๋จ์ ํต์์ ์ผ๋ก ํธ์คํธ์ ์ ์ฅ์ฅ์น์ ํ์ผ๋ก ์กด์ฌํ๋ฏ๋ก ๋ค์์ฒ๋ผ hello.cl ์ ํธ์คํธ์ ๋ฒํผ์ธ source์ ์ฝ์ด์จ๋ค.
[์ฐธ๊ณ ] 06-1 ํ๋ก๋ฆฐ ๋ธ๋ก๊ทธ ์์
// ํ๋ก๊ทธ๋จ์ผ๋ก๋ถํฐ ์ปค๋ ์์ฑ
simpleKernel = clCreateKernel(program, "simpleKernel", NULL);
- kernel์ ์งํฉ์ธ program ๋ด์์ ํน์ ์ปค๋์ ์ ํํด ์ปค๋์ ์คํํ ์ ์๋๋ก ์ปค๋์ ๋ง๋ค๊ณ ์ปค๋์ ํฌ์ธํฐ๋ฅผ ๋ฐํํ๋ ์ฝ๋์ด๋ค.
07 ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ ์์ฑ
cl_program program = NULL;
...
// ๋ฏธ๋ฆฌ ๋ก๋ํ ์์ค ์ฝ๋๋ก ์ปค๋ ํ๋ก๊ทธ๋จ์ ์์ฑ
program = clCreateProgramWithSource(context, 1, (const char **)&source_str, (const size_t *)&source_size, &ret);
- ์์ ๊ฐ์ ์ปค๋ ํ๋ก๊ทธ๋จ์ ์์ค ์ฝ๋๋ฅผ ๊ทธ๋๋ก ์ปค๋๋ก ์ธ์์ํฌ ์ ์๋ค.
- ์ปค๋ ํ๋ก๊ทธ๋จ์๋ ๋ณต์์ ์ปค๋ ํจ์๊ฐ ํฌํจ๋ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
- OpenCL์์๋ ์ปค๋ ํ๋ก๊ทธ๋จ์ ๋จผ์ ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ๋ก ์ธ์์์ผ์ผ ํ๋ค.
- clCreateProgramWithSource()๋ ์์ค ์ฝ๋๋ก๋ถํฐ ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ๊ธฐ ์ํ ํจ์๋ค.- (const char **)&source_str : ์ปค๋ ํ๋ก๊ทธ๋จ์ ์์ค ์ฝ๋- (const size_t *)&source_size : ์์ค ์ฝ๋์ ๋ฌธ์์ด ํฌ๊ธฐ(๋ฐ์ดํธ ๋จ์)
- ํด๋น ํจ์๋ ์ด๋ฆ์์ ์ ์ ์๋ฏ์ด ์ปค๋ ํ๋ก๊ทธ๋จ์ ์์ค ์ฝ๋ ๋ฌธ์์ด๋ก๋ถํฐ ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ์ธ program๋ฅผ ์์ฑํ๋ค.
- ๋ฏธ๋ฆฌ ์ปดํ์ผ๋ ์ปค๋ ํ๋ก๊ทธ๋จ์ ๋ฐ์ด๋๋ฆฌ ํ์ผ์ ๊ฐ์ง๊ณ ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ ๋๋ clCreateProgramWithSource()ํจ์ ๋์ clCreateProgramWithBinary()ํจ์๋ฅผ ์ด์ฉํ๋ค.
[์ฐธ๊ณ ] 07-1 terasic hello example ์์๋ ์๋์ ๊ฐ์ด ์ปค๋ ํ๋ก๊ทธ๋จ ํ์ผ ์ฝ๊ณ ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ ์์ฑ
cl_program program = NULL;
...
// Create the program.
std::string binary_file = getBoardBinaryFile("hello_world", device);
printf("Using AOCX: %s\n", binary_file.c_str());
program = createProgramFromBinary(context, binary_file.c_str(), device, num_devices);
[์ฐธ๊ณ ] 07-2 ํ๋ก๋ฆฐ ๋ธ๋ก๊ทธ ์์
program = clCreateProgramWithSource(context, 1, (const char **)&source, NULL, NULL);
cl_int build_status;
build_status = clBuildProgram(program, 1, &device, NULL, NULL, NULL);
- program์ด๋ kernel์ ์งํฉ์ด๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
- ๊ฐ๋จํ ๋งํด ํ๋ก๊ทธ๋จ ์์ค ํน์ ๋น๋๋ ๋ฐ์ด๋๋ฆฌ์ด๋ค.
08 ์ปค๋ ์ปดํ์ผ
// ์ปค๋ ํ๋ก๊ทธ๋จ ๋น๋
ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);
- ์์ค ์ฝ๋๋ก ๋ฑ๋กํ ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ๋ฅผ OpenCL C ์ปดํ์ผ๋ฌ์ ๋ง์ปค๋ฅผ ์ฌ์ฉํด ๋น๋ํ๋ ๊ณผ์ ์ด๋ค.
- clBuildProgram() ํจ์๋ OpenCL ์ปดํ์ผ๋ฌ์ ๋ง์ปค์ ์ํด ๋น๋๋ฅผ ์คํํ๋ค.- program : ๋น๋ ๋์์ด ๋๋ ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ- ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ 1์ ์ธ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์ ์ง์ ํ ๋๋ฐ์ด์ค ์- &device_id : ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ์ ์ฐ๊ด๋ ๋๋ฐ์ด์ค์ ๋ฆฌ์คํธ๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ- ๋ค ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์๋ ์ปดํ์ผ๋ฌ์๊ฒ ๋๊ฒจ์ค ํ๋ผ๋ฏธํฐ ๋ฌธ์์ด์ ์ง์ ํ๋ค.
- ๋จ, ์ด ์ปดํ์ผ ์ ์ฐจ๋ clCreateProgramWithSource() ํจ์์ ์ํด ์์ค ์ฝ๋๋ก๋ถํฐ ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ์ ๋๋ง ํ์ํ๋ค. clCreateProgramWithBinary() ํจ์๋ฅผ ์ด์ฉํด ์ปดํ์ผ ๋ ๋ฐ์ด๋๋ฆฌ๋ก๋ถํฐ ์ง์ ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ ๋๋ ์ด ์ปดํ์ผ ์ ์ฐจ๊ฐ ํ์์๋ค.
[์ฐธ๊ณ ] terasic hello example ์์๋ ์๋์ ๊ฐ์ด ์ปค๋ ์ปดํ์ผ
// Build the program that was just created.
status = clBuildProgram(program, 0, NULL, "", NULL, NULL);
checkError(status, "Failed to build program");
09 ์ปค๋ ์ค๋ธ์ ํธ ์์ฑ
cl_kernel kernel = NULL;
...
// OpenCL ์ปค๋ ์์ฑ
kernel = clCreateKernel(program, "hello", &ret);
- ์ปดํ์ผ๋ ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ๋ค๋ฉด ์ปค๋ ์ค๋ธ์ ํธ๋ฅผ ์์ฑํด์ผ ํ๋ค.
- ํ๋์ ์ปค๋ ์ค๋ธ์ ํธ๋ ํ๋์ ์ปค๋ ํจ์๋ฅผ ๋ํ๋ธ๋ค. ๋ฐ๋ผ์ ์ปค๋ ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ ๋๋ ๋ค์์ฒ๋ผ ์ปค๋ ํจ์ ์ด๋ฆ์ธ hello๋ฅผ ์ง์ ํ๋ค.
- clCreateKernel() ํจ์๋ ์ปค๋ ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค.- ์ฒซ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ program : ์ปค๋์ ํฌํจํ ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ- ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ "hello" : ์ปค๋ ์ค๋ธ์ ํธ๋ก ์ง์ ํ ์ปค๋ ํจ์ ์ด๋ฆ
- ์ด๋ฒ ์์์๋ ํ๋์ ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ์ ํ๋์ ์ปค๋ ํจ์๋ง์ ์์ฑํ์ง๋ง ์ค์ ๋ก๋ ๋ณต์์ ์ปค๋ ํจ์๋ฅผ ํ๋์ ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ๋ก์ ์์ฑํ ์๋ ์๋ค.
- ์ด๋ ํ๋์ ํ๋ก๊ทธ๋จ ์ค๋ธ์ ํธ๋ก๋ถํฐ ์ฌ๋ฌ ๊ฐ์ ์ปค๋ ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ ์ ์๋ค๋ ์๋ฏธ๋ค. ๋จ, ์ปค๋ ์ค๋ธ์ ํธ์ ์ปค๋ ํจ์๋ 1๋1๋ก ๋์ํ๊ธฐ ๋๋ฌธ์ clCreateKernel() ํจ์๋ฅผ ์ฌ๋ฌ ๋ฒ ํธ์ถํด์ผ ํ๋ค.
[์ฐธ๊ณ ] terasic hello example ์์๋ ์๋์ ๊ฐ์ด ์ปค๋ ์ค๋ธ์ ํธ ์์ฑ
// Create the kernel - name passed in here must match kernel name in the
// original CL file, that was compiled into an AOCX file using the AOC tool
const char *kernel_name = "hello_world"; // Kernel name, as defined in the CL file
kernel = clCreateKernel(program, kernel_name, &status);
checkError(status, "Failed to create kernel");
10 ์ปค๋ ํ๋ผ๋ฏธํฐ ์ค์
// OpenCL ์ปค๋ ํ๋ผ๋ฏธํฐ ์ค์
ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&memobj);
- ์ปค๋ ํจ์๊ฐ ์ป๋ ํ๋ผ๋ฏธํฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๊ณผ์ ์ด๋ค.
- ์ด๋ฒ ์์ ์์๋ ๋ฌธ์์ด ํ์์ ์ปค๋ ํ๋ผ๋ฏธํฐ์ธ string์ ํธ์คํธ์์ ์์ฑํ ๋ฉ๋ชจ๋ฆฌ ์ค๋ธ์ ํธ memobj๋ฅผ ์ ๋ฌํ๋ค.
- ์ด์ฒ๋ผ ํธ์คํธ์์ ํ๋ณดํ ๋ฉ๋ชจ๋ฆฌ ์ค๋ธ์ ํธ๋ฅผ ์ปค๋ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌํ ๋ ์ปค๋ ํ๋ผ๋ฏธํฐ๋ ์ฃผ์ ๊ณต๊ฐ ์์์์ธ __global์ ์ง์ ํด ์ ์ธํ๋ค.
- clSetKernelArg() ํจ์๋ ์ปค๋์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํ ํจ์๋ค.- ์ฒซ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ kernel : ์ปค๋ ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๋ฌํ ์ปค๋ ์ค๋ธ์ ํธ- ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ 0 : ๋๊ฒจ์ค ์ปค๋ ํ๋ผ๋ฏธํฐ์ ์ธ๋ฑ์ค๋ก์ ๋ฒ์๋ 0 ~ ์ปค๋ ํ๋ผ๋ฏธํฐ์-1,- ์ด๋ฒ ์์ ๋ ์ฒซ ๋ฒ์งธ ๋ฌธ์์ด ํ์์ ์ปค๋ ํ๋ผ๋ฏธํฐ์ธ string์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ธฐ ๋๋ฌธ์ 0์ ์ง์ ํจ. ๋ฐ๋ผ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ์ปค๋ ํ๋ผ๋ฏธํฐ๊ฐ ์ฌ๋ฟ ์กด์ฌํ๋ค๋ฉด ์ปค๋ ํ๋ผ๋ฏธํฐ ๊ฐ๊ฐ์ clSetKernelArg() ํจ์๋ก ํธ์ถํ๋ค.- ์ธ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ sizeof(cl_mem) : ๋๊ฒจ์ค ํ๋ผ๋ฏธํฐ์ ํฌ๊ธฐ๋ฅผ ์ง์ - ๋ค ๋ฒ์งธ ํ๋ผ๋ฏธํฐ (void *)&memobj : ์ ๋ฌํ ๋ฐ์ดํฐ๋ก ๋ฉ๋ชจ๋ฆฌ ์ค๋ธ์ ํธ memobj๋ฅผ ์ง์
- ํด๋น ์์ ์์๋ ๋ฉ๋ชจ๋ฆฌ ์ค๋ธ์ ํธ๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ์ง์ ํ๋ค. ๋ง์ฝ ํธ์คํธ์ ๋ฐ์ดํฐ๋ฅผ ์ปค๋ ํ๋ผ๋ฏธํฐ๋ก ์ง์ ์ ๋ฌํ๋ ค๋ฉด ์๋์ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ๋ค.
int a = 10;
clSetKernelArg(kernel, 0, sizeof(int), (void *)&a);
[์ฐธ๊ณ ] terasic hello example ์์๋ ์๋์ ๊ฐ์ด ์ปค๋ ํ๋ผ๋ฏธํฐ ์ค์
// Set the kernel argument (argument 0)
status = clSetKernelArg(kernel, 0, sizeof(cl_int), (void*)&thread_id_to_output);
checkError(status, "Failed to set kernel arg 0");
[์ฐธ๊ณ ] terasic vector example ์์๋ ์๋์ ๊ฐ์ด ์ปค๋ ํ๋ผ๋ฏธํฐ ์ค์
// Set kernel arguments.
unsigned argi = 0;
status = clSetKernelArg(kernel[i], argi++, sizeof(cl_mem), &input_a_buf[i]);
checkError(status, "Failed to set argument %d", argi - 1);
status = clSetKernelArg(kernel[i], argi++, sizeof(cl_mem), &input_b_buf[i]);
checkError(status, "Failed to set argument %d", argi - 1);
status = clSetKernelArg(kernel[i], argi++, sizeof(cl_mem), &output_buf[i]);
checkError(status, "Failed to set argument %d", argi - 1);
11 ์ปค๋ ์คํ
// OpenCL ์ปค๋ ์คํ
ret = clEnqueueTask(command_queue, kernel, 0, NULL, NULL);
- ์์ ์ฝ๋๋ ํธ์คํธ์์ ๋๋ฐ์ด์ค๋ก ์ปค๋์ ์คํํ๋ ๊ณผ์ , ๋๋ฐ์ด์ค์๊ฒ ํ์คํฌ๋ฅผ ๋งก๊ธฐ๊ธฐ ์ํด ์ปค๋งจ๋ ํ์ ํ์คํฌ๋ฅผ ์ ๋ฌํ๋ ๊ตฌ๋ฌธ์ด๋ค.
- hello๋ผ๋ ์ปค๋์ ์คํํ๋ ๋ช ๋ น์ clEnqueueTask() ํจ์์ ์ํด ํ์ ์ ๋ฌ๋ ํ ๋๋ฐ์ด์ค ์์ ์คํ ๊ฐ๋ฅํ ์ฐ์ฐ ์ ๋์์ ์คํํ๋ค.
- clEnqueueTask() ํจ์๋ ์ปค๋งจ๋ ํ์ ๋ช ๋ น์ ์ ๋ฌํ ๋ฟ์ด๋ฏ๋ก ํธ์คํธ์์ ํธ์ถํ clEnqueueTask() ํจ์์ ์คํ์ด ๋๋ ์์ ์์๋ hello๋ผ๋ ์ปค๋์ ์คํ์ด (๋๋ฐ์ด์ค์์) ์ข ๋ฃ๋์๋ค๊ณ ๋ณด์ฅํ ์ ์๋ค.
- clEnqueueTask() ํจ์๊ฐ ์ ์ ์ข ๋ฃ๋์์ ๋๋ hello์ ์คํ์ ์๋ฏธํ๋ ๋ช ๋ น์ด ์ปค๋งจ๋ ํ์ ์ ๋๋ก ์ ๋ฌ๋์๋ค๋ ์ ๋ง ๋ณด์ฅํ ๋ฟ์ด๋ค. ์ฆ, ์ค์ ๋ก ๋๋ฐ์ด์ค ์์์ hello์ ์คํ์ด ์ข ๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ค๋ฉด ๋ค์ฏ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ฅผ ํตํด์ ์ด๋ฒคํธ ์ค๋ธ์ ํธ๋ฅผ ์ป์ด์ผํ๋ค.
- clEnqueueTask() ํจ์๋ ํ์คํฌ ๋ณ๋ ฌ์ ์คํํ ๋ ์ฌ์ฉํ๋ค.
- ๋ฐ์ดํฐ ๋ณ๋ ฌ์ ์คํํ ๋๋ ์ธ๋ฑ์ค ๊ณต์ฐ ์ค์ ์ ํ์๋ก ํ๋ clEnqueueNDRangeKernel() ํจ์๋ฅผ ์ฌ์ฉํ๋ค. -> ์๋ ์์ ์ฐธ๊ณ
[์ฐธ๊ณ ] terasic vector example ์์๋ ์๋์ ๊ฐ์ด ์ปค๋ ์คํ
// Launch the kernel
status = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, gSize, wgSize, 0, NULL, NULL);
checkError(status, "Failed to launch kernel");
12 ๋ฉ๋ชจ๋ฆฌ ์ค๋ธ์ ํธ ๋ก๋
char string[MEM_SIZE];
...
// ์คํ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ๋ชจ๋ฆฌ ๋ฒํผ์์ ์ป์
ret = clEnqueueReadBuffer(command_queue, memobj, CL_TRUE, 0, MEM_SIZE * sizeof(char), string, 0, NULL, NULL);
- ํธ์คํธ์์ ์ปค๋์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๋ ค๋ฉด ๋๋ฐ์ด์ค์ ๋ฉ๋ชจ๋ฆฌ ์์ญ์์ ํธ์คํธ์ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์กํด์ผ ํ๋ค.
- clEnqueueReadBuffer()๋ ๋๋ฐ์ด์ค์ ๋ฉ๋ชจ๋ฆฌ์์ ํธ์คํธ์ ๋ฉ๋ชจ๋ฆฌ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๊ธฐ ์ํ ํจ์๋ค. ๋ฐ๋๋ก ํธ์คํธ ๋ฉ๋ชจ๋ฆฌ์์ ๋๋ฐ์ด์ค ๋ฉ๋ชจ๋ฆฌ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ๋๋ clEnqueueWriteBuffer() ํจ์๋ฅผ ์ด์ฉํ๋ค.
- ํจ์ ์ด๋ฆ์ 'Enqueue'๊ฐ ํฌํจ๋ ๊ฒ์ ๋๋ฐ์ด์ค๋ฅผ ์กฐ์ํ๋ ํจ์์ธ ๊ฒ !!
- clEnqueueReadBuffer() ํจ์๋ ์ปค๋งจ๋ ํ์ ๋ฉ๋ชจ๋ฆฌ ๋ช ๋ น์ด ์ ๋ฌ๋ ํ ๋ฐ์ดํฐ ๋ณต์ฌ๋ฅผ ์์ํ๋ค.- ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ memobj : ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด๋ค์ผ ๋๋ฐ์ด์ค ์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ํ๋ด๋ ๋ฉ๋ชจ๋ฆฌ ์ค๋ธ์ ํธ๋ฅผ ์ง์ - ์ธ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ CL_TRUE : ๋๊ธฐ ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ๋ฅผ ํ๊ฒ ๋ค๋ ๋ป, string์ ๋ณต์ฌ๊ฐ ๋๋ ๋๊น์ง clEnqueueReadBuffer() ํจ์๋ ์ข ๋ฃ๋์ง ์๋๋ค.-> ๋ง์ฝ CL_FALSE๋ฅผ ์ง์ ํ๋ฉด ๋น๋๊ธฐ ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ๋ฅผ ํ๊ฒ ๋ค๋ ๋ป, ์ปค๋งจ๋ ํ์ ๋ณต์ฌ ๋ช ๋ น์ด ์ ๋๋ก ์ ๋ฌ๋๋ฉด ์ค์ ๋ฐ์ดํฐ ๋ณต์ฌ๊ฐ ๋๋์ง ์๋๋ผ๋ clEnqueueReadBuffer() ํจ์๊ฐ ์ข ๋ฃ๋๋ค.- ๋ค์ฏ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ MEM_SIZE * sizeof(char) : ๋ณต์ฌํ ๋ฐ์ดํฐ์ ํฌ๊ธฐ(๋ฐ์ดํธ)๋ฅผ ์ง์ - ์ฌ์ฏ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ string : ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ํธ์คํธ ์์ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ๋ํ ํฌ์ธํฐ๋ฅผ ์ง์
- ํธ์คํธ์์ clEnqueueReadBuffer() ํจ์์๊ฒ ๋๋ฐ์ด์ค์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฝ์ผ๋ผ๋ ์ง์๋ฅผ ๋ด๋ฆฌ๊ธฐ ์ , hello ์ปค๋์ด ๋ฐ๋์ ์ข ๋ฃ๋์๋ค๊ณ ํ ์ ์์๊น? ์ ๋ํ ์ง๋ฌธ- ํธ์คํธ์ ์ปค๋ ์คํ ํจ์ clEnqueueTask()๋ ํ์ ์ ๋ฌ๋ ์ง์ ์์ ๋น ์ ธ๋์จ๋ค.- ์ปค๋์ ์คํ์ด ๋๋๊ธฐ ์ ์ ๋๋ฐ์ด์ค์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฝ๋๋ค๋ฉด ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์์ง๋ง Enqueue ๊ณ์ด์ ํจ์๋ ํธ์คํธ์์ ๋ณด๋ฉด ๋น๋๊ธฐ ํธ์ถ์ด์ง๋ง ์ปค๋งจ๋ ํ์ ํฌ์ ๋ ๋ช ๋ น์ ์คํ ์์๋ ์ปค๋งจ๋ ํ ์์ฑ์ ํน๋ณํ ์ง์ ์ ํ์ง ์๋ ์ด์ ๋๊ธฐ ์คํ(ํ์ ์ ๋ฌ๋ ์์๋๋ก ๋ช ๋ น์ ์คํ)์ด๋ฏ๋ก ์ฐ๋ คํ ํ์ ์๋ค.- ์ด๋ฒ ์๋ ์ปค๋งจ๋ ํ์ ๋น๋๊ธฐ ์คํ ์ง์๋ฅผ ๋ด๋ฆฌ์ง ์์๊ธฐ ๋๋ฌธ์ ๋จผ์ ํ์ ์ ๋ฌ๋ ์ปค๋ ์คํ ๋ช ๋ น์ด ์ข ๋ฃ๋ ๊ฒ์ ํ์ธํ ํ ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ ๋ช ๋ น์ด ์คํ๋๋ค.
[์ฐธ๊ณ ] terasic hello example ์์๋ ์ฝ์ ๊ฒ์ด ์์
[์ฐธ๊ณ ] terasic vector example ์์๋ ์๋์ ๊ฐ์ด ๋ฉ๋ชจ๋ฆฌ ์ค๋ธ์ ํธ ๋ก๋
// Read the result. This the final operation.
status = clEnqueueReadBuffer(queue[i], output_buf[i], CL_FALSE, 0, n_per_device[i] * sizeof(float), output[i], 1, &kernel_event[i], &finish_event[i]);
13 ์ค๋ธ์ ํธ ํด์
ret = clReleaseKernel(kernel);
ret = clReleaseProgram(program);
ret = clReleaseMemObject(memobj);
ret = clReleaseCommandQueue(command_queue);
ret = clReleaseContext(context);
- ํ๋ก๊ทธ๋จ์ ์์ ํ ์ข ๋ฃ๋ฅผ ์ํด ์์ฑํ ๊ฐ์ข ์ค๋ธ์ ํธ๋ฅผ ํด์ ํด์ผ ํ๋ค.
- ์ฌ์ฉ์ด ๋๋ ์ค๋ธ์ ํธ๋ ์ฌ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ์์ฑ๊ณผ ํด์ ๋ฅผ ๋งค๋ฒ ์ค์ํ ํ์๋ ์๋ค.
- ์ค์ ํ๋ก๊ทธ๋จ์์๋ ์ปค๋ ํ๋ผ๋ฏธํฐ์ ์ค์ ํน์ ์ ๋ ฅ ๋ฒํผ๋ฅผ ํตํด ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ -> ์ปค๋ ์คํ -> ๋ฉ๋ชจ๋ฆฌ ์ฝ๊ธฐ๋ฅผ ๋ฐ๋ณตํ๋ ๊ฒ์ด ๊ธฐ๋ณธ์ด๋ค.
- ์ค๋ธ์ ํธ๋ฅผ ์์ฑ๋ง ํ๊ณ ํด์ ์ํค์ง ์์ผ๋ฉด์ ๊ณ์ ์ฌ์ฉํ๋ฉด ํธ์คํธ์ ๊ฐ์ข ์ค๋ธ์ ํธ ๊ด๋ฆฌ์ฉ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ด ๋ถ์กฑํด์ง๋ค. ์ด ๋๋ OpenCL ๋ฐํ์์ด ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ ์๋ฌ๋ฅผ ๋ฐํํ๋ค.
[์ฐธ๊ณ ] 13-1 terasic hello example ์์๋ ์๋์ ๊ฐ์ด ์ค๋ธ์ ํธ ํด์
// Free the resources allocated during initialization
void cleanup() {
if (kernel) {
clReleaseKernel(kernel);
}
if (program) {
clReleaseProgram(program);
}
if (queue) {
clReleaseCommandQueue(queue);
}
if (context) {
clReleaseContext(context);
}
}
728x90
728x90
'๐ก EE's DEV > FPGA' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[OpenCL] VS 2017์์ OpenCL ์ฌ์ฉํ๊ธฐ (0) | 2018.08.08 |
---|---|
[FPGA] NIOS II Tutorial Helloworld (0) | 2018.08.08 |