在朱莉娅,我主要看到当我处理矩阵时,能够对代码进行调整和优化,例如,
- 按列而不是按行工作,这是Julia存储矩阵的方式。
-On循环可以使用@inbounds
和@simd
宏
- 你可以推荐它的任何功能,宏或方法:D
但是当我使用存储在GPU上的矩阵的ArrayFire包时,上面的示例似乎不起作用,CPU和GPU中的类似代码似乎不支持在某些情况下运行速度慢得多的GPU,I认为它不应该是这样的,我认为问题在于编写代码。欢迎任何帮助
答案 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计算将会很快。