0

我只想更改一个元素,如下面的代码所示。

using Flux, CuArrays

a = rand(3,3) |> gpu
CuArrays.allowscalar(false)
a[1, 1] = 1.0f0

因为allowscalar设置为false,所以自然会出现如下。

ERROR: scalar setindex! is disallowed

但是如果allowscalar被删除,它会如下所示。

Performing scalar operations on GPU arrays: This is very slow, consider disallowing these operations with allowscalar(false)

我在访问元素的部分之前和之后打开和关闭了“allowscalar”。然后,它比“allowscalar”设置为 true 时慢了大约 20 倍。

接下来,我尝试在 CPU 上创建另一个矩阵,然后在 GPU 上将这些矩阵相加,如下所示。

b = zeros(Float32, 3, 3)
b[1, 1] = 1.0f0
b = b |> gpu
a .+= b

但是,如果我假设我可以像下面这样单独在 GPU 上完成它,它会快 4 倍左右。

a .*= 1.0f0 # Dummy calculations that do some processing on the GPU
a .+= a # Dummy calculations that do some processing on the GPU

如何访问 CuArray 中的元素并更改其值?我希望早日收到你的来信。

4

2 回答 2

0

我在访问元素的部分之前和之后打开和关闭了“allowscalar”。然后,它比“allowscalar”设置为 true 时慢了大约 20 倍。

切换allowscalar不应影响性能。事实上,当需要使用某些 API 检查单个元素时,CuArrays 本身就会这样做。该函数的宏版本可以很容易地做到这一点:

julia> a = CuArrays.rand(3,3);

julia> CuArrays.allowscalar(false)

julia> a[1, 1] = 1.0f0
ERROR: scalar setindex! is disallowed

julia> CuArrays.@allowscalar a[1, 1] = 1.0f0
1.0f0

julia> a
3×3 CuArray{Float32,2,Nothing}:
 1.0       0.277899   0.333898
 0.126213  0.0881365  0.794662
 0.94518   0.586488   0.656359

julia> a[1, 1] = 1.0f0
于 2020-04-28T09:34:27.033 回答
0

谢谢您的回答。不过我有一个问题。Maleadt先生说“切换allowscalar不应该影响性能。”但是,在我的程序中,它似乎有点不同。

using Flux, CuArrays, CUDAnative
a = CuArrays.rand(50, 50);
@time for i in 1:10000
    b = sum(CUDAnative.log.(a))
end
12.222549 seconds (4.25 M allocations: 151.379 MiB, 1.05% gc time)

另一方面,

using Flux, CuArrays, CUDAnative
a = CuArrays.rand(50, 50);

CuArrays.allowscalar(false)

@time for i in 1:10000
    CuArrays.@allowscalar b = sum(CUDAnative.log.(a))
end
16.512146 seconds (4.21 M allocations: 151.733 MiB, 0.57% gc time)

为什么会这样?

于 2020-04-29T21:46:53.990 回答