什么是OpenCL

百度百科飞机票✈
OpenCL是一个为异构平台编写程序的框架,此异构平台可由CPU,GPU或其他类型的处理器组成。OpenCL由一门用于编写kernels (在OpenCL设备上运行的函数)的语言(基于C99)和一组用于定义并控制平台的API组成。OpenCL提供了基于任务分割和数据分割的并行计算机制。

上面是官方的一些解释,大体上是指用于编写运行在异构平台上的程序的一种框架,由特定的数据类型,数据结构,和一些API组成接口组成,说实话,我个人觉得它并不是一门语言,其实就是在C/C++的基础上去做的扩展罢了。

为什么是OpenCL

OpenCL不局限于某一个平台或者设备,并不像早期的NVIDIA 的CUDA,只支持自己的的显卡并行计算,而这也成为了OpenCL成为主流并行计算框架之一的原因。
CPU/GPU系统系统昭示着未来超级计算发展的方向,实现跨平台架构的应用程序,以及最大的利用计算机硬件资源。
标准化的向量处理,想想我们在图像视频领域做数据处理迭代成千上百万次的循环,但是在GPU 上,只需要一次。

纸牌游戏

刚开始接触OpenCL的时候,被各种数据结构类型,各式各样的术语吓到,比如context上下文,host主机,kernel内核,平台,设备,指令等等。
但是我们可以做一个类比: 庄家扮演OpenCL主机host的角色,一般是CPU.。每个玩家则是兼容OpenCL的设备(CPU/GPU/FPGA/DSP/其他加速设备等)。桌子就相当于OpenCL的平台(plantform),每个人的手牌就相当于指令序列。当然以上就是为了让大家了解OpenCL所做的简单类比,并不是很严谨。

代码示例

下面介绍一个简单的代码示例
矩阵-向量的乘法运算

matvec.c

#define _CRT_SECURE_NO_WARNINGS
#define PROGRAM_FILE "matvec.cl"
#define KERNEL_FUNC "matvec_mult"#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>#ifdef MAC
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endifint main() {/* Host/device data structures */cl_platform_id platform;cl_device_id device;cl_context context;cl_command_queue queue;cl_int i, err;/* Program/kernel data structures */cl_program program;FILE *program_handle;char *program_buffer, *program_log;size_t program_size, log_size;cl_kernel kernel;/* Data and buffers */float mat[16], vec[4], result[4];float correct[4] = {0.0f, 0.0f, 0.0f, 0.0f};cl_mem mat_buff, vec_buff, res_buff;size_t work_units_per_kernel;/* Initialize data to be processed by the kernel */for(i=0; i<16; i++) {mat[i] = i * 2.0f;} for(i=0; i<4; i++) {vec[i] = i * 3.0f;correct[0] += mat[i]    * vec[i];correct[1] += mat[i+4]  * vec[i];correct[2] += mat[i+8]  * vec[i];correct[3] += mat[i+12] * vec[i];      }/* Identify a platform */err = clGetPlatformIDs(1, &platform, NULL);if(err < 0) {perror("Couldn't find any platforms");exit(1);}/* Access a device */err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);if(err < 0) {perror("Couldn't find any devices");exit(1);}/* Create the context */context = clCreateContext(NULL, 1, &device, NULL, NULL, &err);if(err < 0) {perror("Couldn't create a context");exit(1);   }/* Read program file and place content into buffer */program_handle = fopen(PROGRAM_FILE, "r");if(program_handle == NULL) {perror("Couldn't find the program file");exit(1);   }fseek(program_handle, 0, SEEK_END);program_size = ftell(program_handle);rewind(program_handle);program_buffer = (char*)malloc(program_size + 1);program_buffer[program_size] = '\0';fread(program_buffer, sizeof(char), program_size, program_handle);fclose(program_handle);/* Create program from file */program = clCreateProgramWithSource(context, 1, (const char**)&program_buffer, &program_size, &err);if(err < 0) {perror("Couldn't create the program");exit(1);   }free(program_buffer);/* Build program */err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);if(err < 0) {/* Find size of log and print to std output */clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);program_log = (char*) malloc(log_size + 1);program_log[log_size] = '\0';clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, log_size + 1, program_log, NULL);printf("%s\n", program_log);free(program_log);exit(1);}/* Create kernel for the mat_vec_mult function */kernel = clCreateKernel(program, KERNEL_FUNC, &err);if(err < 0) {perror("Couldn't create the kernel");exit(1);   }/* Create CL buffers to hold input and output data */mat_buff = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(float)*16, mat, &err);if(err < 0) {perror("Couldn't create a buffer object");exit(1);   }      vec_buff = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(float)*4, vec, NULL);res_buff = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(float)*4, NULL, NULL);/* Create kernel arguments from the CL buffers */err = clSetKernelArg(kernel, 0, sizeof(cl_mem), &mat_buff);if(err < 0) {perror("Couldn't set the kernel argument");exit(1);   }         clSetKernelArg(kernel, 1, sizeof(cl_mem), &vec_buff);clSetKernelArg(kernel, 2, sizeof(cl_mem), &res_buff);/* Create a CL command queue for the device*/queue = clCreateCommandQueue(context, device, 0, &err);if(err < 0) {perror("Couldn't create the command queue");exit(1);   }/* Enqueue the command queue to the device */work_units_per_kernel = 4; /* 4 work-units per kernel */ err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &work_units_per_kernel, NULL, 0, NULL, NULL);if(err < 0) {perror("Couldn't enqueue the kernel execution command");exit(1);   }/* Read the result */err = clEnqueueReadBuffer(queue, res_buff, CL_TRUE, 0, sizeof(float)*4, result, 0, NULL, NULL);if(err < 0) {perror("Couldn't enqueue the read buffer command");exit(1);   }/* Test the result */if((result[0] == correct[0]) && (result[1] == correct[1])&& (result[2] == correct[2]) && (result[3] == correct[3])) {printf("Matrix-vector multiplication successful.\n");}else {printf("Matrix-vector multiplication unsuccessful.\n");}/* Deallocate resources */clReleaseMemObject(mat_buff);clReleaseMemObject(vec_buff);clReleaseMemObject(res_buff);clReleaseKernel(kernel);clReleaseCommandQueue(queue);clReleaseProgram(program);clReleaseContext(context);return 0;
}

matvec.cl

__kernel void matvec_mult(__global float4* matrix,__global float4* vector,__global float* result) {int i = get_global_id(0);result[i] = dot(matrix[i], vector[0]);
}

Makefile

PROJ=matvecCC=gccCFLAGS=-std=c99 -Wall -DUNIX -g -DDEBUG# Check for 32-bit vs 64-bit
PROC_TYPE = $(strip $(shell uname -m | grep 64))# Check for Mac OS
OS = $(shell uname -s 2>/dev/null | tr [:lower:] [:upper:])
DARWIN = $(strip $(findstring DARWIN, $(OS)))# MacOS System
ifneq ($(DARWIN),)CFLAGS += -DMACLIBS=-framework OpenCLifeq ($(PROC_TYPE),)CFLAGS+=-arch i386elseCFLAGS+=-arch x86_64endif
else# Linux OS
LIBS=-lOpenCL
ifeq ($(PROC_TYPE),)CFLAGS+=-m32
elseCFLAGS+=-m64
endif# Check for Linux-AMD
ifdef AMDAPPSDKROOTINC_DIRS=. $(AMDAPPSDKROOT)/includeifeq ($(PROC_TYPE),)LIB_DIRS=$(AMDAPPSDKROOT)/lib/x86elseLIB_DIRS=$(AMDAPPSDKROOT)/lib/x86_64endif
else# Check for Linux-Nvidia
ifdef NVSDKCOMPUTE_ROOTINC_DIRS=. $(NVSDKCOMPUTE_ROOT)/OpenCL/common/inc
endifendif
endif$(PROJ): $(PROJ).c$(CC) $(CFLAGS) -o $@ $^ $(INC_DIRS:%=-I%) $(LIB_DIRS:%=-L%) $(LIBS).PHONY: cleanclean:rm $(PROJ)

OpenCL学习笔记一相关推荐

  1. OpenCL学习笔记——整体流程(向量相加)

    OpenCL学习笔记--整体流程 OpenCL可以实现混合设备的并行计算,这些设备包括CPU,GPU,以及其他处理器,比如Cell处理器,DSP等.使用OpenCL编程,可以实现可以值得并行加速代码. ...

  2. OpenCL学习笔记(三):OpenCL安装,编程简介与helloworld

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术.应用感兴趣的同学加入. OpenCL安装 安装我不打算 ...

  3. OpenCL学习笔记(一):摩尔定律,异构计算与OpenCL初印象

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术.应用感兴趣的同学加入. 关于摩尔定律: 摩尔定律196 ...

  4. openCVPracticalExercise学习笔记01

    原创:openCVPracticalExercise学习笔记01 资料:OpenCV-Practical-Exercise:https://github.com/luohenyueji/OpenCV- ...

  5. 2012年9月9日参加中国软件开发者大会学习笔记

    2012年9月9日参加中国软件开发者大会学习笔记 全文请访问:http://bbs.hpx-party.org/thread-74667-1-1.html 欢迎转发新浪微博:http://weibo. ...

  6. 嵌入式算法移植优化学习笔记5——CPU,GPU,TPU,NPU都是什么

    嵌入式算法移植优化学习笔记5--CPU,GPU,TPU,NPU都是什么 一.什么是CPU? 二.什么是GPU? 三.什么是NPU? 四.什么是TPU? 附: 随着AI的广泛应用,深度学习已成为当前AI ...

  7. 【DOTS学习笔记】DOTS简介

    目录 前言 DOTS是什么? 核心Package 游戏功能相关Package 谁需要关注DOTS? DOTS可以应用到哪些地方? 为什么需要DOTS 前言 本文是Metaverse大衍神君的<D ...

  8. 人工智能概论学习笔记(一):CPU GPU

    人工智能概论学习笔记(一):CPU & GPU 作者:王洋子豪 链接:https://www.zhihu.com/question/19903344/answer/13779421 来源:知乎 ...

  9. PCL学习笔记-PCL简介

    PCL(点云库)学习笔记 1.简介 点云数据的处理可以采用获得广泛应用的Point Cloud Library(点云库,PCL库). PCL库是一个最初发布于 2013年的开源c++库,它实现了大量点 ...

最新文章

  1. python奇数和_请问python如何判断奇偶数?
  2. TensorFlow--实现人脸识别实验精讲 (Face Recognition using Tensorflow)
  3. 包打包和解析过程 unity_Unity学习—资源管理概览
  4. python开发环境有哪些特点_快速了解Python开发环境Spyder
  5. qt.qpa.screen: QXcbConnection: Could not connect to display(vnpy,云主机,图形界面)
  6. 伯克利人工智能导论课开放:视频、PPT和练习都在这 | 资源
  7. oracle性能优化总结1
  8. JAVA 中 Redis与ehcache对比与使用
  9. PHP foreach使用 引用 的坑
  10. Atitit 资源类型的分类法规范MIME类型类型 目录 1.1. 一个MIME类型至少包括两个部分:一个类型(type)和一个子类型(subtype)。 1 1.2. 命名格式MIME类型包括一个
  11. H3C 100F防火墙限速
  12. 黑苹果系统发热与续航
  13. 微软梁念坚谈新平台 企业跨界办公随需而变
  14. Unity给力插件之Final IK
  15. App开发者不再遵循苹果iOS设计惯例
  16. Linux spi驱动分析(四)----SPI设备驱动(W25Q32BV)
  17. iOS 音乐 锁屏显示 控制
  18. 寒江独钓NDIS驱动学习总结
  19. 小米10等UFS字库备份与基带分区说明
  20. 天下没有不会这么回事!不会就学——北漂18年(28)

热门文章

  1. 【JavaScript】内容的展开/收起
  2. Oracle HINT的常见用法
  3. AutoIt v3.3.14.2 汉化最新版
  4. 大连东软计算机专业全国排名,大连东软信息学院就业怎么样?全国前三,名不虚传!...
  5. xlsx VLOOKUP 怎么用
  6. 线程安全问题及解决方法
  7. Android 编程_基础
  8. docker安装redis无法启动: The container name “/ly-redis“ is already in use by container
  9. 这11个免费学习的网站,个个堪称神器,不收后悔!
  10. python调用ironpython_在.NET中嵌入IronPython 交互