其他
移动端异构运算技术-GPU OpenCL 编程(基础篇)
The following article is from 百度App技术 Author 谢柏渊
一、前言
(注:Apple 对于 GPU 推荐的使用方式是 Metal,此处暂不做展开)
2.1 异构计算
2.2 GPU
3.1 OpenCL 编程模型
平台模型(Platform Model)
执行模型 (Execution Model)
内存模型 (Memory Model)
宿主内存(Host Memory):宿主 CPU 可直接访问的内存。 全局/常量内存 (Global/Constant Memory):可以用于计算设备中的所有计算单元。 本地内存(Local Memory):对计算单元中的所有处理元素可用。 私有内存(Private Memory):用于单个处理元素。
3.2 OpenCL 编程
初始化 OpenCL 相关环境,如 cl_device、cl_context、cl_command_queue 等
cl_int status;
// init device
runtime.device = init_device();
// create context
runtime.context = clCreateContext(nullptr, 1, &runtime.device, nullptr, nullptr, &status);
// create queue
runtime.queue = clCreateCommandQueue(runtime.context, runtime.device, 0, &status);
初始化程序要执行的 program、kernel
cl_int status;
// init program
runtime.program = build_program(runtime.context, runtime.device, PROGRAM_FILE);
// create kernel
runtime.kernel = clCreateKernel(runtime.program, KERNEL_FUNC, &status);
准备输入输出,设置到 CLKernel
// init datas
float input_data[ARRAY_SIZE];
float bias_data[ARRAY_SIZE];
float output_data[ARRAY_SIZE];
for (int i = 0; i < ARRAY_SIZE; i++) {
input_data[i] = 1.f * (float) i;
bias_data[i] = 10000.f;
}
// create buffers
runtime.input_buffer = clCreateBuffer(runtime.context, CL_MEM_READ_ONLY |
CL_MEM_COPY_HOST_PTR, ARRAY_SIZE * sizeof(float), input_data, &status);
runtime.bias_buffer = clCreateBuffer(runtime.context, CL_MEM_READ_ONLY |
CL_MEM_COPY_HOST_PTR, ARRAY_SIZE * sizeof(float), bias_data, &status);
runtime.output_buffer = clCreateBuffer(runtime.context, CL_MEM_READ_ONLY |
CL_MEM_COPY_HOST_PTR, ARRAY_SIZE * sizeof(float), output_data, &status);
// config cl args
status = clSetKernelArg(runtime.kernel, 0, sizeof(cl_mem), &runtime.input_buffer);
status |= clSetKernelArg(runtime.kernel, 1, sizeof(cl_mem), &runtime.bias_buffer);
status |= clSetKernelArg(runtime.kernel, 2, sizeof(cl_mem), &runtime.output_buffer);
执行获取结果
// clEnqueueNDRangeKernel
status = clEnqueueNDRangeKernel(runtime.queue, runtime.kernel, 1, nullptr, &ARRAY_SIZE,
nullptr, 0, nullptr, nullptr);
// read from output
status = clEnqueueReadBuffer(runtime.queue, runtime.output_buffer, CL_TRUE, 0,
sizeof(output_data), output_data, 0, nullptr, nullptr);
// do with output_data
...
1. OpenCL-Guide
https://github.com/KhronosGroup/OpenCL-Guide/blob/main/chapters/opencl_programming_model.md
2. OpenCL-Examples
https://github.com/rsnemmen/OpenCL-examples