Effectively adding a scalar to a matrix in Julia

I need to add a scalar to all elements of a huge matrix. The matrix will be as large as possible. In this example, I will use 2 GiB size, but in my real calculation it will be much larger.

A = rand(2^14, 2^14)

If I do

A += 1.0

Julia allocates an additional 2 gigabytes of memory. The operation takes about 1 second. I could use a loop for:

for jj = 1:size(A, 2), ii = 1:size(A, 1)
  A[ii, jj] = A[ii, jj] + 1.0
end

It does not allocate any memory, but it takes one minute. Both approaches are not viable for me, because the first violates the memory limitations, and the second is clearly inefficient. For elementary multiplication, there is scal!one that uses BLAS. Is there a way to do the addition as efficiently as the multiplication using scal!?

+4
2

@DSM - . , , . , , , A - , . A , A . A A[ii, jj] = A[ii, jj] + 1.0 - getindex, + setindex!, A. , :

julia> A = rand(2^10, 2^10);

julia> @time for jj = 1:size(A, 2), ii = 1:size(A, 1)
           A[ii, jj] += 1
       end
elapsed time: 0.288340785 seconds (84048040 bytes allocated, 15.59% gc time)

julia> function inc!(A)
           for jj = 1:size(A, 2), ii = 1:size(A, 1)
               A[ii, jj] += 1
           end
       end
inc! (generic function with 1 method)

julia> @time inc!(A)
elapsed time: 0.006076414 seconds (171336 bytes allocated)

julia> @time inc!(A)
elapsed time: 0.000888457 seconds (80 bytes allocated)

, , . , .

inc! @inbounds, , :

julia> function inc!(A)
           @inbounds for i = 1:length(A)
               A[i] += 1
           end
       end
inc! (generic function with 1 method)

julia> @time inc!(A)
elapsed time: 0.000637934 seconds (80 bytes allocated)

@inbounds, , . @inbounds , , , . , , , . .

+11

:

julia> A = rand(2^14, 2^14); A[1:5, 1:5]
5x5 Array{Float64,2}:
 0.229662  0.680236    0.131202  0.111664   0.802698
 0.500575  0.580994    0.385844  0.983806   0.324382
 0.701694  0.577749    0.532591  0.0508955  0.94325 
 0.592929  0.00319653  0.759241  0.448704   0.706204
 0.867945  0.0413606   0.586151  0.82561    0.679233

julia> @time broadcast!(.+, A, A, 100);
elapsed time: 0.382669486 seconds (11490976 bytes allocated)

julia> A[1:5, 1:5]
5x5 Array{Float64,2}:
 100.23   100.68   100.131  100.112  100.803
 100.501  100.581  100.386  100.984  100.324
 100.702  100.578  100.533  100.051  100.943
 100.593  100.003  100.759  100.449  100.706
 100.868  100.041  100.586  100.826  100.679

~ 2G .

+6

All Articles