不同计算器上的矩阵乘法
在此示例中,我们将向您展示如何使用工具包研究代码性能。 BenchmarkTools 让我们比较它在CPU和GPU上的执行。
连接到GPU
目前,GPU资源对用户的可用性仍然是Engee平台的一个高级功能。 GPU是一种图形显卡,允许您通过在位于图形协处理器内部的数万个计算内核上执行代码来显着并行执行代码。
使用GPU的主库是 CUDA.jl. 让我们安装这个库,并用它来评估代码性能的工具包(包 BenchmarkTools).
# Закомментируйте эту строку, если будете устанавливать библиотеки другим образом
Pkg.add( url="https://github.com/JuliaBinaryWrappers/CUDA_Runtime_jll.jl.git" )
Pkg.add( ["CUDA", "cuDNN", "Flux", "BenchmarkTools"] );
Pkg.instantiate()
Cpu上的矩阵乘法
让我们看看在传统处理器上矩阵乘法平均需要多长时间。
N = 1_000
A = rand(ComplexF64, (N,N))
B = rand(ComplexF64, (N,N))
using BenchmarkTools
@benchmark A*B
执行此单元格可能需要相当长的时间,因为命令 @benchmark 多次运行分配给她的操作,以消除朱莉娅固有的"热身"效应。 当代码意外显示尽可能低的性能时,它还可以减少罕见条件的影响。
在这种特殊情况下,实验表明,将1000乘以1000个复数矩阵平均需要300毫秒。
GPU上的矩阵乘法
要将图形卡上的矩阵相乘,需要将它们转移到它,这可以通过多种方式完成。 例如,用命令 A |> gpu 但是,由于系统中可能没有GPU,我们将检查计算空间的配置并选择可用的计算机。
转移矩阵后 Matrix 现在他们是对象 CuArray. 它们的乘法在没有额外代码的情况下执行(由于乘法运算符的重载)。 但乘以矩阵 A_gpu 在矩阵上 B 我们不能这样做,而不将两个矩阵转移到同一个计算器(否则你会得到一个错误 KernelError: kernel returns a value of type Union{}).
using CUDA, Flux
if CUDA.functional()
A_gpu = A |> gpu
B_gpu = B |> gpu
@benchmark A_gpu * B_gpu
end
GPU上的最小操作时间几乎比GPU上的最小计算时间少10,000倍(41微秒对384毫秒)。
结论
Julia允许您将计算传输到GPU,以便可以多次加速各种应用的计算,而无需重写其代码。 我们在处理器和显卡上进行了矩阵乘法,并确定了1000乘1000的方阵,由随机复数组成,显卡比CPU快几万倍。