最近有不少朋友在多次循环执行OpenCL内核程序的时候碰到一些问题。由于对OpenCL初学者而言可能比较普遍,因此我这里给出一个清晰简单的demo来掩饰如何简单又高效地执行循环执行OpenCL内核。
以下程序的大概意思与流程是:
-
内核程序含有两个参数,第一个参数既是输入又是输出,第二个参数仅仅用于输入。不过第一个参数只对其初始化一次,而第二个参数在每次循环执行新一次的内核程序前会再传递一次数据。这么做有助于同学更好地去理解、把握存储器对象的基本使用方法。
-
存储器对象在通过
cl_context上下文创建完之后,其所在的GPU端的位置就不变了。因此,我们在循环执行内核程序之前不需要把存储器对象释放掉,然后重新分配。这么做就比较低效了。我们完全可以重用同一个存储器对象。
以下代码在我的MacBook Air上能完全通过编译执行。没有任何warning。
执行环境:基于Haswell微架构的Intel Core i7 4650U,Intel HD Graphics 5000,8GB DDR3L,128GB SSD。
macOS 10.9.2 Mavericks,Xcode 5.1,Apple LLVM 5.1,支持GNU11标准的C编译器。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif
int main(void)
{
cl_int ret;
cl_platform_id platform_id = NULL;
cl_device_id device_id = NULL;
cl_context context = NULL;
cl_command_queue command_queue = NULL;
cl_mem memObj1 = NULL;
cl_mem memObj2 = NULL;
char *kernelSource = NULL;
cl_program program = NULL;
cl_kernel kernel = NULL;
int *pInputBuffer1 = NULL;
int *pInputBuffer2 = NULL;
int *pOutputBuffer = NULL;
clGetPlatformIDs(1, &platform_id, NULL);
if(platform_id == NULL)
{
puts("Get OpenCL platform failed!");
goto FINISH;
}
clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);
if(device_id == NULL)
{
puts("No GPU available as a compute device!");
goto FINISH;
}
context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &ret);
if(context == NULL)
{
puts("Context not establis

该文提供了一个简单的OpenCL程序示例,展示如何高效地循环执行内核,重点在于内存对象的重用和避免不必要的释放与重新分配。代码在Mac环境下通过编译,包括设置内核参数、数据传输和结果验证等步骤。
1427

被折叠的 条评论
为什么被折叠?



