CUDA&OpenCL编程7个技巧及ArrayFire如何帮助您
为了让你的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,跨度))。