0
点赞
收藏
分享

微信扫一扫

机器学习与计算机视觉(opencl编程)

扒皮狼 2022-11-23 阅读 102



 

    因为学习cuda的原因,所以最近一段时间对GPU编程比较感兴趣。大家都知道,cuda是属于nvidia公司的产品,那么我就在想,对于其他公司开发的GPU产品,他们是怎么做的?结果就是opencl编程。

 

1、opencl编程

    opencl支持nvidia、ati、arm等多个gpu,也可以在嵌入式设备上完成。

 

2、opencl的编译环境

    大部分安装了gpu的编程环境,比如说cuda sdk,就可以开发opencl编程了。

 

3、最简单的opencl代码

​​https://github.com/giobauermeister/OpenCL-test-apps/blob/master/cl_sample_timer/cl_sample_timer.c​​

 

4、编译opencl代码的时候需要注意什么

    在链接的时候添加OpenCL.lib即可

 

5、查询opencl设备信息

    用到的api主要就是两个,clGetPlatformIDs & clGetPlatformInfo

#include <stdio.h>  
#include <stdlib.h>
#include <iostream>
#include <CL/cl.h>


int main()
{
//cl_platform 表示一个OpenCL的执行平台,关联到GPU硬件,如N卡,AMD卡
cl_platform_id *platforms;

//OpenCL中定义的跨平台的usigned int和int类型
cl_uint num_platforms;
cl_int i, err, platform_index = -1;

char* ext_data;
size_t ext_size;
const char icd_ext[] = "cl_khr_icd";

//要使platform工作,需要两个步骤。1 需要为cl_platform_id结构分配内存空间。2 需要调用clGetPlatformIDs初始化这些数据结构。一般还需要步骤0:询问主机上有多少platforms

//查询计算机上有多少个支持OpenCL的设备
err = clGetPlatformIDs(5, NULL, &num_platforms);
if (err < 0)
{
perror("Couldn't find any platforms.");
exit(1);
}
printf("本机上支持OpenCL的环境数量: %d\n", num_platforms);

//为platforms分配空间
platforms = (cl_platform_id*)
malloc(sizeof(cl_platform_id) * num_platforms);

clGetPlatformIDs(num_platforms, platforms, NULL);

//获取GPU平台的详细信息
for (i = 0; i < num_platforms; i++)
{
//获取缓存大小
err = clGetPlatformInfo(platforms[i],
CL_PLATFORM_EXTENSIONS, 0, NULL, &ext_size);
if (err < 0)
{
perror("Couldn't read extension data.");
exit(1);
}

printf("缓存大小: %d\n", ext_size);

ext_data = (char*)malloc(ext_size);

//获取支持的扩展功能
clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS,
ext_size, ext_data, NULL);
printf("平台 %d 支持的扩展功能: %s\n", i, ext_data);

//获取显卡的名称
char *name = (char*)malloc(ext_size);
clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME,
ext_size, name, NULL);
printf("平台 %d 是: %s\n", i, name);

//获取显卡的生产商名称
char *vendor = (char*)malloc(ext_size);
clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR,
ext_size, vendor, NULL);
printf("平台 %d 的生产商是: %s\n", i, vendor);

//获取平台版本
char *version = (char*)malloc(ext_size);
clGetPlatformInfo(platforms[i], CL_PLATFORM_VERSION,
ext_size, version, NULL);
printf("平台 %d 的版本信息: %s\n", i, version);

//查询显卡是独立的还是嵌入的
char *profile = (char*)malloc(ext_size);
clGetPlatformInfo(platforms[i], CL_PLATFORM_PROFILE,
ext_size, profile, NULL);
printf("平台 %d 是独立的(full profile)还是嵌入式的(embeded profile)?: %s\n", i, profile);

//查询是否支持ICD扩展
if (strstr(ext_data, icd_ext) != NULL)
platform_index = i;
std::cout << "平台ID = " << platform_index << std::endl;
/* Display whether ICD extension is supported */
if (platform_index > -1)
printf("平台 %d 支持ICD扩展: %s\n",
platform_index, icd_ext);
std::cout << std::endl;

//释放空间
free(ext_data);
free(name);
free(vendor);
free(version);
free(profile);
}

if (platform_index <= -1)
printf("No platforms support the %s extension.\n", icd_ext);
getchar();

//释放资源
free(platforms);
return 0;
}

6、opencl和cuda的相同之处

    opencl和cuda结构上差不多,一部分api代码都是在cpu运行的,只有kernel部分的代码才是在gpu上运行的。当然除了c语言之外,opencl和cuda都是支持python的,将kernel代码传给python就可以了,使用起来不复杂。

 

7、opencl和cuda的关系

    opencl&cuda有点类似于opengl&direct x的关系。对于跨平台来说,opencl更好,但是cuda的生态更棒。本身cuda除了cudnn之外,还提供了很多的第三方库,这些对于需要数学库移植的同学来说太方便了。

 

8、个人怎么学习使用

     如果是在nvidia的环境开发,那么多多使用cuda,总归没有错的。但是如果arm系列的gpu,opencl基本上是你唯一的选择。不然,你只能使用neon指令去加速一些特殊的算法了。

 

9、opencl & opencv

    现在很多朋友使用opencl加速opencv的效果不明显,建议可以自己编写opencv算法、测试高分辨率图片、用很多图片来测试算法,看看原因出在哪里。另外测试的时候多让图像在gpu保存,不要在cpu和gpu之间搬来搬去,这样很浪费时间。

 

其他:

    当然,现在除了opencl,也有一种并发框架,类似于openmp,它就是openacc,​​https://www.openacc.org/get-started​​

    参考代码链接在这​​https://yq.aliyun.com/articles/71262​​,内容如下

#include<stdio.h>
#define N 256
int main()
{
int i,a[N],b[N],c[N];
for(i=0;i<N;i++)
{
a[i]=0;
b[i]=c[i]=i;
}
#pragma acc kernels
for(i=0;i<N;i++)
{
a[i]=b[i]+c[i];
}
printf("a[N-1]=%d \n",a[N-1]);
return 0;

}

ps:

    目前soc上面的dsp、fpga、gpu、nn其实都是可以用来数据计算的。只不过因为功耗、习惯、技术积累的原因,通常我们只使用其中的一种技术。这个时候,就要适当多了解一下其他硬件编程技术。不管从哪方面讲,opencl&cuda都是非常不错的,既满足了并发的要求,而且学习难度上也小很多。dsp&fpga太小众了,nn也是每一家都有自己的方案,自己能控制的可能只剩下GPU编程这一种了。

 

    安装了cuda之后,就可以opencl编程

    

 

举报

相关推荐

0 条评论