CUDA&OpenCL编程7个技巧及ArrayFire如何帮助您
2013-02-17 21:42
363 查看
为了让你的CUDA或者OpenCL代码有更好的性能,这里将有一些有用的优化性能的技巧.注意:在这里说的“加速器”是指GPU、APU、协处理器、FPGA和所有可以支持CUDA或OpenCL的设备。
· 向量化代码Vectorized Code: 加速器执行向量化代码性能会很好因为计算自然地映射到硬件的运算内核上。ArrayFire函数本质上是量化的,因此,如果您使用ArrayFire,你正在编写向量化代码。
· 内存传输:避免过多的内存传输。每个casting操作在CPU存储器和加速器存储器之间来回移动数据。 ArrayFire已经做了很多自动优化,以尽量减少这些存储器之间的传输,只有在万不得已才传输数据。
· 串行对比并行运算: CPU是串行计算设备,而加速器是并行计算设备。对于小的或者并行运算,在CPU上就可以实现最好的性能。而对于大型或者并行运算,可能在加速器上能实现很好的性能。经验之谈是对于只有几百元素的数据就用CPU,如果你的数据规模 >10,000 元素,就用加速器。有了ArrayFire,你可以通过创建矩阵数据类型来控制运行在每个设备的代码段。
· 循环: 循环通常意味着串行处理。但是,如果迭代间没有数据依赖关系,有了CUDA或者OpenCL,就可以同时运行所有的迭代。ArrayFire的 GFOR函数可以很容易地实现。
· Lazy Execution: 用CUDA和OpenCL很重要的一点是构建内核,这些内核执行适量的计算,没有太多的超时,也不会降低吞吐量。ArrayFire 采用了一个lazy execution,可以根据你的算法自动构建最佳的内核。Lazy Execution也意味着无论是在显示或随后的基于CPU的计算中,ArrayFire不启动GPU的内核,直到请求结果。如果你想强制一个ArrayFire计算,可以用ArrayFire sync和eval函数。
· 一个好的计时代码: 计时代码写的不好,常可引起人为加速器性能下降。 ArrayFire配备了一个方便的计时功能,以确保适当的基准。
· 定期访问模式:当执行下标时,请记住,加速器内存控制器是不像在CPU上那么多用途。实现最佳性能时,你的下标访问模式是定期和统一。例如,A([1 4 2 35 1 2...])将会变慢,而A([12 3 4 56...])将更快。使用ArrayFire,下标是很容易的。 ArrayFire是列主序的,所以它是更快地访问列(A(跨度,i)),而不是行(A(i,跨度))。
· 向量化代码Vectorized Code: 加速器执行向量化代码性能会很好因为计算自然地映射到硬件的运算内核上。ArrayFire函数本质上是量化的,因此,如果您使用ArrayFire,你正在编写向量化代码。
· 内存传输:避免过多的内存传输。每个casting操作在CPU存储器和加速器存储器之间来回移动数据。 ArrayFire已经做了很多自动优化,以尽量减少这些存储器之间的传输,只有在万不得已才传输数据。
· 串行对比并行运算: CPU是串行计算设备,而加速器是并行计算设备。对于小的或者并行运算,在CPU上就可以实现最好的性能。而对于大型或者并行运算,可能在加速器上能实现很好的性能。经验之谈是对于只有几百元素的数据就用CPU,如果你的数据规模 >10,000 元素,就用加速器。有了ArrayFire,你可以通过创建矩阵数据类型来控制运行在每个设备的代码段。
· 循环: 循环通常意味着串行处理。但是,如果迭代间没有数据依赖关系,有了CUDA或者OpenCL,就可以同时运行所有的迭代。ArrayFire的 GFOR函数可以很容易地实现。
· Lazy Execution: 用CUDA和OpenCL很重要的一点是构建内核,这些内核执行适量的计算,没有太多的超时,也不会降低吞吐量。ArrayFire 采用了一个lazy execution,可以根据你的算法自动构建最佳的内核。Lazy Execution也意味着无论是在显示或随后的基于CPU的计算中,ArrayFire不启动GPU的内核,直到请求结果。如果你想强制一个ArrayFire计算,可以用ArrayFire sync和eval函数。
· 一个好的计时代码: 计时代码写的不好,常可引起人为加速器性能下降。 ArrayFire配备了一个方便的计时功能,以确保适当的基准。
· 定期访问模式:当执行下标时,请记住,加速器内存控制器是不像在CPU上那么多用途。实现最佳性能时,你的下标访问模式是定期和统一。例如,A([1 4 2 35 1 2...])将会变慢,而A([12 3 4 56...])将更快。使用ArrayFire,下标是很容易的。 ArrayFire是列主序的,所以它是更快地访问列(A(跨度,i)),而不是行(A(i,跨度))。
相关文章推荐
- opencv,openGL,CUDA,opencl区别&&一些名词的区别
- Enterprise Library 2.0 技巧(4):如何用编程的方法来配置Logging Application Block
- 编程技巧:如何创建颜色
- 编程技巧:使用LINQ如何通过多次调用GroupBy实现分组嵌套
- 使用LINQ来简化编程的7个技巧
- java程序员如何编写更好的单元测试的7个技巧
- JAVA编程技巧之如何实现HTTP的断点续传
- python高效编程技巧5(如何快速找到多个字典中的公共键)
- CUDA与OpenCL编程框架的比较
- 【编程之法】如何最快的判断出短字符串b中的所有字符是否都在长字符串a中?编写函数bool StringContain(string&b,string&a)实现此功能。
- 编程技巧——c#.net mvc:如何读取xml文档
- GPGPU OpenCL/CUDA 高性能编程的10大注意事项
- 【Cuda并行编程之一】二分查找的探究以及Cuda的简单实现&&相关面试题介绍
- 7个高级技巧帮助你释放大量Mac OS X硬盘空间
- OpenCL & CUDA
- RCP编程技巧:如何显示Mysql数据库中存储的图片?
- 编程技巧:如何使用线程
- 《Java 编程技巧1001条》 第422条: 如何退出应用程序
- JAVA编程技巧之如何实现HTTP的断点续传(原理篇)
- GPU&VS2012&CUDA&matlab&Arrayfire杂记(一)——序