Opencl 在线和离线编译

OpenCL支持在线编译和离线编译两种编译方式,主要区别是内核程序提供给主机调用方式。

mark

  • 在线编译:在host程序中引用的是Kernel的源代码建立Opencl程序
  • 离线编译:Host程序中直接能在目标器件上运行的二进制文件来简历opencl程序

离线编译中,kernel程序使用Opencl编译器提前编译出二进制文件,在主机程序中使用Opencl API来调用编译好的二进制文件。由于主程序中直接调用二进制执行文件,所以从主程序启动到内核运行之间的时间是很小的。但是这样做的问题是很难实现加速设备的通用性,在提供给客户运行的程序中就必须要把所有可能的平台都包进来,还必须在主程序中分类调用,增加了主机程序的复杂性。同时可执行文件也大了很多。

在线编译中,内核是在运行环境中(runtime)通过Opencl API库编译内核源代码。有点类似于Just in time 编译–JIT编译解释。这种方法的优点就是可以不依赖于具体设备类型的就可以发布主机端程序,程序会在运行的时候自动去适配具体的设备。同时避免每次都去编译内核,减少了开发测试的负担。但是这种方式不适合需要达到实时效果的嵌入式系统。同时由于可以从主机程序中读取到内核程序,并不适于商业应用。

Opencl运行库包含了一组能完全实现上面操作的API。某种程度上来说,由于Opencl是一个异构环境的编程框架,支持在线编译并不是个稀奇的事情。事实上,NVIDIA,AMD和APPLE的OPENCL环境并没有一个完全独立的OPENCL编译器。因此,如果需要在这些环境中得到一个内核二进制文件,还需要主机程序在执行的时候把编译出来的执行文件写进一个文档。

比较在线编译和离线编译示例:

在线编译
先从文件中读取内核原代码

const char fileName[] = "./kernel.cl";
...
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);

然后在主程序中使用clCreateProgramWithSource使用源代码创建程序,并使用clBuildProgram实现在线编译

/* Create Kernel program from the read in source */
    program = clCreateProgramWithSource(context, 1, (const char **)&source_str, (const size_t *)&source_size, &ret);

/* Build Kernel Program */
    ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);

离线编译
先读取内核程序的二进制文件

char fileName[] = "./kernel.clbin";
...
fp = fopen(fileName, "r");
if (!fp) {
    fprintf(stderr, "Failed to load kernel.\n");
    exit(1);
}
binary_buf = (char *)malloc(MAX_BINARY_SIZE);
binary_size = fread(binary_buf, 1, MAX_BINARY_SIZE, fp);
fclose(fp);

然后使用clCreateProgramWithBinary使用二进制创建程序

/* Create kernel program from the kernel binary */
    program = clCreateProgramWithBinary(context, 1, &device_id, (const size_t *)&binary_size,(const unsigned char **)&binary_buf, &binary_status, &ret);

对比可以发现不需要使用clBuildProgram()编译

原文中作者安装了foxc编译器,这个编译器有独立的内核编译器,可以让读者可以更清楚的了解在线编译和离线编译的过程。
作者使用了foxc -o kernel.clbin kernel.cl编译出独立的内核二进制文件

原文:opencl在线和离线编译

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值