爱上OpenCL的十个理由

作为OpenCL CodeBench的开发者,Amdahl软件公司始终坚信OpenCL能够带来巨大的利益,也从未怀疑过OpenCL标准的成功性。现在人们对计算性能的要求越来越高,在不超过发热量和功耗的限制范围,我们相信多核和多核系统提供了一个可行的解决方法。对于OpenCL用户来说,OpenCL标准的优点和利益是很明显的。我们认为在未来的几十年甚至超过几十年里,OpenCL将会引领计算机软件行业。

下面是我们为什么觉得OpenCL强大的最重要的10个理由。

1-OpenCL可以为代码加速10倍甚至更多

现在许多的嵌入式或者桌面计算平台在主板上都有GPU。但是,大部分时间GPU都是闲置的,除非该计算平台正在运行图形敏感的工作。通过利用空闲的GPU的计算能力,你可以加速代码的运行。假如你的算法本身就是并行的,那么利用GPU可以加速的更多。对于分子动力学模拟,甚至电子电路,实时视频处理,图像处理,图像增强,移动侦测,财务分析和自动交易等方面的应用特别适合利用GPU来进行加速。

GPU并不是唯一可以利用OpenCL加速的设备。如果你的主机平台有多个CPU核——而且现在越来越多的台式电脑拥有四个核或者更多的核——在这种情况下你同样可以使用OpenCL进行CPU的多核编程。利用OpenCL进行CPU多核编程可能达不到利用GPU加速的效果,但这取决于加速的算法,不过随着CPU核数的增加性能也会随之提高。

2-OpenCL是一个开放标准

OpenCL是一个开放的标准意味着该标准对于所有使用OpenCL的人来说都是免费的,开放的。OpenCL有一系列高品质的文档,包括在线教程、编程指南和参考手册。除此之外,我们还可以找到很多关于的OpenCL的开源工具和出版的书籍,而且我们还可以利用互联网找到很多的使用案例和设计实例。

3-OpenCL可以降低功耗

现在存在很多的工业例子证明对加速器的使用可以降低系统能耗。Amdahl软件公司在不久的将来会出版一本白皮书,该书使用直接的定量分析的方式表明使用简单的CPU+GPU模型来降低功耗的机会。与此同时,Imagination Technologies公司提供的OpenCL视频例子很好的展示了这一点。

4-OpenCL可以节省你的硬件成本

对于数字信号处理(DSP),OpenCL提供了一种宽松的浮点实现。如果你的算法不需要绝对的精确,你可以在系统中取消DSP,使用已有的GPGPU代替。

5-OpenCL正在快速的普及

这对于桌面和嵌入式世界都是正确的。半导体和IP供应商,像Altera, Apple, AMD, ARM, Freescale, IBM, Imagination, Intel, NVidia, Samsung, STMicroelectronics, Texas Instruments, Vivante, Qualcomm等已经宣布了他们的OpenCL兼容设备。在Khronos的OpenCL兼容产品资料库可以找到完整的兼容设备和驱动清单。随着其他设备兼容性的测试,这个清单会迅速扩大。通过使用OpenCL,现在越来越多的库和最终用户应用正在被移植到OpenCL平台,以利用GPGPU的加速能力。OpenCL的使用提高了应用的性能,为最终用户的体验和期望设定了新的标准。

6-OpenCL可以被用作产生自定义硬件的基础

OpenCL编程模型在本质上是通过对内核,工作组和工作项的定义来实现并行。在内核中,甚至可以通过使用有着固定的众所周知长度的小型矢量数据类型进行更细粒度的并行度划分。在高效数据访问过程中,OpenCL另外一个重要的组成特性是内核能够通过barrier和memory fence进行同步的能力。所有这些特性使得OpenCL不仅仅适合编程以用来进行软件加速,也适合对自定义硬件加速器实现的定义。Altera公司已经意识到了这一点,它最近发布了一个程序,该程序提供了从OpenCL移植到FPGA的实现方式。

开发人员的应用程序不再受限于存在的设备。相反,他们可以通过OpenCL定义特定的“co-processor”来进行系统优化,以满足他们的特殊要求(性能,功耗,大小)。设计人员可以在一个已知的并易于调试的环境下开发一个功能全面并已通过测试的的并行应用。一旦完成了代码的编写,影响性能的关键代码部分可以通过FPGA image来进行完美的加速,该FPGA image是程序涉及到的内核直接产生的,这是OpenCL的一个很重要的好处。这促进了一种紧密的集成硬件/软件协同设计方法的行成,在该方法中,同一个基准程序和测试贯穿整个开发过程,这样就加快了应用进入市场的时间。

7-OpenCL C99语言是基于C语言的

这是一个不应该被忽略的特性。创建一种全新的编程语言会减慢对OpenCL的采纳速度——尽管它可能会带来巨大的利益。C语言是一种工业标准语言,它是OpenCL的基础。OpenCL kernel定义语言是对C99的扩展,简单易于接受。对于会使用C编程的工程师来说,能够很快的掌握OpenCL。这样,程序员就可以集中精力在他们想要加速的算法上,而不是OpenCL的语法上。

8-OpenCL可以被用于各种各样的宿主语言

OpenCL kernel可以在C , C++, Java, Python, JavaScript, Haskell, Perl, Ruby等宿主语言中调用,而且能够调用OpenCL的语言还在增多。这就使得在不同的开发环境下可以进行OpenCL kernel和结果的移植和复用,使得对GPGPU计算的支持更加灵活。

9-很容易开始OpenCL

大部分的PC机都有兼容OpenCL的显卡。如果你的计算系统没有GPU(不太可能的情况),只要你找到相应可用的驱动,你同样可以在CPU上直接运行OpenCL程序。在嵌入式世界中,存在很多支持OpenCL的开发板。许多的GPU供应商除了提供了OpenCL的培训视频和教程,还提供了很多关于OpenCL的应用笔记和示例程序。所以要想开始OpenCL编程是很便宜,很简单的事情。

10-OpenCL是平台独立的

OpenCL的编程模型是平台独立的,它能够用来进行异构的多核的软件开发。不同的内存空间定义了一个内存一致的模型。在OpenCL代码运行时,从用户的角度看,低层级的任务例如队列和执行内核是被屏蔽的,是不可见的。在OpenCL中,events,barrier和fences提供了同步的能力。

OpenCL平台的独立性意味着在不修改代码的前提下就能够让代码在不同的兼容的OpenCL平台上运行。因此,即使在不同的平台运行同一OpenCL代码性能可能会有所不同,但是从一个平台将OpenCL代码移植到另一个平台是很简单的。OpenCL在基于共有系统模型的基础上提供了一个功能性的起点。

结论

我们坚信OpenCL潜在的能力。OpenCL使得软件工程师可以有效的利用(易购的)多核计算的能力。不管在什么编程环境下,用来进行开发的工具越好,开发效率就越高,代码的质量就越好。在多核的时代下,我们使用OpenCL CodeBench的目的就是简化OpenCL的开发。OpenCL CodeBench提供了全面的主机代码生成功能,还提供了基于Eclipse的智能便捷的OpenCL kernel编辑器。不要一味的相信我们的话,你可以自己去试试用OpenCL CodeBench进行编程,你将会发现要加速你的应用是件多么简单多么快捷的事情。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的 OpenCL 示例程序,用于将一个数组中的元素求和: ``` #include <stdio.h> #include <stdlib.h> #include <CL/cl.h> #define MAX_SOURCE_SIZE (0x100000) int main() { cl_platform_id platform_id = NULL; cl_device_id device_id = NULL; cl_uint num_devices, num_platforms; cl_int ret; // Step 1: Get the platform and device information ret = clGetPlatformIDs(1, &platform_id, &num_platforms); ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id, &num_devices); // Step 2: Create a context cl_context context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &ret); // Step 3: Create a command queue cl_command_queue queue = clCreateCommandQueue(context, device_id, 0, &ret); // Step 4: Create the kernel program from source code FILE *fp; char fileName[] = "./sum.cl"; char *source_str; size_t source_size; fp = fopen(fileName, "r"); if (!fp) { printf("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); cl_program program = clCreateProgramWithSource(context, 1, (const char **)&source_str, (const size_t *)&source_size, &ret); // Step 5: Build the kernel program ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL); // Step 6: Create the kernel object cl_kernel kernel = clCreateKernel(program, "sum", &ret); // Step 7: Set the kernel arguments int n = 1000; int *A = (int*) malloc(n*sizeof(int)); int sum = 0; for (int i = 0; i < n; ++i) { A[i] = i; sum += i; } cl_mem bufA = clCreateBuffer(context, CL_MEM_READ_ONLY, n*sizeof(int), NULL, &ret); cl_mem bufC = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(int), NULL, &ret); ret = clEnqueueWriteBuffer(queue, bufA, CL_TRUE, 0, n*sizeof(int), A, 0, NULL, NULL); ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&bufA); ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&bufC); // Step 8: Execute the kernel on the device size_t global_item_size = n; size_t local_item_size = 64; ret = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global_item_size, &local_item_size, 0, NULL, NULL); // Step 9: Read the result back to the host int result; ret = clEnqueueReadBuffer(queue, bufC, CL_TRUE, 0, sizeof(int), &result, 0, NULL, NULL); printf("Sum using OpenCL: %d\n", result); printf("Sum using CPU: %d\n", sum); // Step 10: Clean up ret = clFlush(queue); ret = clFinish(queue); ret = clReleaseKernel(kernel); ret = clReleaseProgram(program); ret = clReleaseMemObject(bufA); ret = clReleaseMemObject(bufC); ret = clReleaseCommandQueue(queue); ret = clReleaseContext(context); free(A); return 0; } ``` 这个程序包含以下步骤: 1. 获取平台和设备信息。 2. 创建一个 OpenCL 上下文。 3. 创建一个 OpenCL 命令队列。 4. 从源代码中创建一个内核程序。 5. 编译内核程序。 6. 创建内核对象。 7. 设置内核参数。 8. 在设备上执行内核。 9. 从设备上读取结果。 10. 清理资源。 需要注意的是,程序中使用了一个名为 `sum.cl` 的内核代码文件。这个文件的内容如下: ``` __kernel void sum(__global const int *A, __global int *C) { int i = get_global_id(0); if (i < 1000) { C[0] = 0; atomic_add(&C[0], A[i]); } } ``` 这个内核代码用于将一个长度为 1000 的整型数组中的元素求和,并将结果写入一个整型变量中。程序中使用了 `clEnqueueNDRangeKernel` 函数来执行内核,并使用 `clEnqueueReadBuffer` 函数将结果从设备上读取到主机内存中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值