一直以为julia里面调用gpu需要用CUDAdrv, CUDAnative等库,其中CUDAnative的文档最全,但是有个谜之问题:
这里的threads在我这里不能大于1024,这就是说我一次只能计算1024个array元素运算,其结果是速度感人。
昨天看了如何在Julia编程中实现GPU加速发现其实比较基础的原始的可以CuArrays库就简单实现,而且速度可以。
julia> using CuArrays
julia> using BenchmarkTools
julia> A=rand(Float32, 100000);
julia> AA = cu(A);
julia> B=rand(Float32, 100000);
julia> BB = cu(B);
julia> @btime A+B;
49.800 μs (2 allocations: 390.70 KiB)
julia> @btime AA+BB;
6.040 μs (46 allocations: 1.75 KiB)
julia> CC=AA+BB;
julia> C2=collect(CC);
julia> C=A+B;
julia> using Test
julia> @test C ≈ C2
Test Passed
julia> @test C == C2
Test Passed
julia>
如有错误,请赐教
Gnimuc
2
如果直接用 CudaNative 这种底层库,你需要做的跟直接用 cuda 做 GPU 加速没什么太大区别,要把算法“分块”, 根据 GPU 的参数来选则分块大小 blocksize 。CudaNative 默认 block 数为 1,那文档只是一个简单的例子,你可以将 blocks * threads
作为 problem size。
运行 如何在Julia编程中实现GPU加速代码的话请注意,改小数据范围,否则爆内存
Gnimuc
4
这是 cuda 的限制,一般像是 (1024,1024,64)有 API 可以查询 3 个维度各限制多大。
Gnimuc
5
不想自己整 kernel 就用这种上层库吧,简单常用的基本够用,不过有局限性就是了。
嗯,修正了,并简单测试了一下,原来默认的blocks是1。
using CuArrays
using BenchmarkTools
a=rand(Float32,1024100);
b=rand(Float32,1024100);
aa=cu(a);
bb=cu(b);
d_a = CuArray(a);
d_b = CuArray(b);
d_c = similar(d_a);
function kernel_vadd(a, b, c)
i = (blockIdx().x-1) * blockDim().x + threadIdx().x
c[i] = a[i] + b[i]
return nothing
end
@btime @cuda blocks=100 threads=1024 kernel_vadd(d_a, d_b, d_c);
@btime aa+bb;
@btime a+b;
结果是,果然底层的快一些
julia> @btime @cuda blocks=100 threads=1024 kernel_vadd(d_a, d_b, d_c);
4.086 μs (22 allocations: 752 bytes)
julia> @btime aa+bb;
6.200 μs (46 allocations: 1.75 KiB)
julia> @btime a+b;
46.999 μs (2 allocations: 400.08 KiB)
谢谢了,我还是贴截图算了,代码我可能不会贴,已经第二次出现贴出来的代码个别字符变字符了
Jun
拆分了此话题
10
A post was split to a new topic: CuArrays 在Windows 10 上的安装