在Julia中编写代码的最好方法是通过ArrayFire在GPU上工作

时间:2017-11-15 04:40:33

标签: julia arrayfire

在朱莉娅,我主要看到当我处理矩阵时,能够对代码进行调整和优化,例如,

- 按列而不是按行工作,这是Julia存储矩阵的方式。

-On循环可以使用@inbounds@simd

- 你可以推荐它的任何功能,宏或方法:D

但是当我使用存储在GPU上的矩阵的ArrayFire包时,上面的示例似乎不起作用,CPU和GPU中的类似代码似乎不支持在某些情况下运行速度慢得多的GPU,I认为它不应该是这样的,我认为问题在于编写代码。欢迎任何帮助

1 个答案:

答案 0 :(得分:3)

GPU计算应尽可能在优化的GPU内核上完成。索引GPU阵列是一个小内核,它将一个值复制回CPU。这对性能来说真的很糟糕,所以除非必须,否则你几乎不应该为GPUArray编制索引(对于任何实现都是如此!这只是一个硬件问题!)

因此,您应该编写广播(“矢量化”)代码,而不是为GPU编写循环代码。使用v0.6 broadcast changes,广播操作几乎与循环一样有效(除非你点击this bug),所以没有理由在通用代码中避免使用它们。但是,有些情况下广播比循环更快,GPU也是一个大案例。

让我解释一下为什么。当您执行代码时:

@. A = B*C + D*E

降低到

A .= B.*C .+ D.*E

然后降低到:

broadcast!((b,c,d,e)->b*c + d*e,A,B,C,D,E)

请注意,在那里你有一个融合的匿名函数用于整个广播。对于GPUArrays,然后将其覆盖,以便自动创建单个GPU内核,以逐个元素执行此融合操作。因此,只需要一个GPU内核即可完成整个操作!请注意,这比执行GPU计算的R / Python / MATLAB方法更有效,因为这些矢量化形式有临时性,并且需要4个内核,但这没有临时数组并且是单个内核,这几乎是如此如果你自己编写内核,你会写它。因此,如果您利用广播,那么您的GPU计算将会很快。