Why is x(:) so much slower than reshape(x,N,1) with complex arrays?
9 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
The two for loops below differ only in the flattening operation used to obtain A_1D . Why is the run time so much worse with A_3D(:) than with a call to reshape()?
Nx = 256;
Ny = 256;
Nz = 128;
N = Nx*Ny*Nz;
A0 = rand(N,1);
tic
for k = 1:20
B = reshape( A0, [Nz,Ny,Nx] ) ;
A_3D = fftn(B);
A_1D = reshape( A_3D, N,1); %<--- Version 1
end
toc
tic
for k = 1:20
B = reshape( A0, [Nz,Ny,Nx] ) ;
A_3D = fftn(B);
A_1D = A_3D(:); %<--- Version 2
end
toc
7 Commenti
Bruno Luong
il 28 Lug 2021
I must admit that understanding why/when MATLAB make data copy become obscure to me since few years now. I did not come to a full understanding of how it works.
Risposta accettata
Matt J
il 28 Lug 2021
8 Commenti
G A
il 14 Ago 2021
Walter, I am discussing complex valued arrays, it can be
max(A,[],'all')
but anyway for a complex number max(A) = max(abs(A))
Walter Roberson
il 14 Ago 2021
The (:) options are the slowest. reshape(abs(A),N,1) might possibly be the fastest -- there is notable variation in different runs.
Nx = 256;
Ny = 256;
Nz = 128;
N = Nx*Ny*Nz;
A0 = complex(randn(Nx, Ny, Nz), randn(Nx, Ny, Nz));
t(1) = timeit(@() use_abs_all(A0, N), 0)
t(2) = timeit(@() use_abs_colon(A0, N), 0)
t(3) = timeit(@() use_abs_reshape_null(A0, N), 0)
t(4) = timeit(@() use_abs_reshape_N(A0, N), 0)
t(5) = timeit(@() use_all(A0, N), 0)
t(6) = timeit(@() use_colon(A0, N), 0)
t(7) = timeit(@() use_reshape_null(A0, N), 0)
t(8) = timeit(@() use_reshape_N(A0, N), 0)
cats = categorical({'abs(all)', 'abs(:)', 'reshape(abs,[])','reshape(abs,N)', 'all', '(:)', 'reshape([])', 'reshape(N)'});
bar(cats, t)
function B = use_abs_all(A, N)
B = max(abs(A), [], 'all');
end
function B = use_abs_colon(A, N)
B = max(abs(A(:)));
end
function B = use_abs_reshape_null(A, N)
B = max(reshape(abs(A), [], 1));
end
function B = use_abs_reshape_N(A, N)
B = max(reshape(abs(A), N, 1));
end
function B = use_all(A, N)
B = max(A, [], 'all');
end
function B = use_colon(A, N)
B = max(A(:));
end
function B = use_reshape_null(A, N)
B = max(reshape(A, [], 1));
end
function B = use_reshape_N(A, N)
B = max(reshape(A, N, 1));
end
Più risposte (2)
Walter Roberson
il 28 Lug 2021
Nx = 256;
Ny = 256;
Nz = 128;
N = Nx*Ny*Nz;
A0 = rand(Nx, Ny, Nz);
timeit(@() use_colon(A0, N), 0)
timeit(@() use_reshape_null(A0, N), 0)
timeit(@() use_reshape_N(A0, N), 0)
function use_colon(A, N)
B = A(:);
end
function use_reshape_null(A, N)
B = reshape(A, [], 1);
end
function use_reshape_N(A, N)
B = reshape(A, N, 1);
end
In this particular test, the timing is close enough that we can speculate some reasons:
Using an explicit size to reshape to is faster than reshape([]) because reshape([]) has to spend time calculating the size based upon dividing numel() by the size of the known parameters.
Using (:) versus reshape() is not immediately as clear. The model for (:) is that it invokes subsref() with struct('type', {'()'}, 'subs', {':'}) and then subsref() has to invoke reshape() . I point out "model" because potentially the Execution Engine could optimize all of this, and one would tend to think that optimization of (:) should be especially good.
10 Commenti
Walter Roberson
il 11 Ago 2021
I had the hypothesis that the 5 might have to do with my having 4 cores, or might have to do with the number of priming iterations I did, so I tested on my system that has more cores, and I did more priming iterations. The result was the same: duration(1,1) still had the major peak, and duration(5,1) was reliably a seconary peak.
Adam Danz
il 12 Ago 2021
I noticed that when I re-run it within a script without clearing variables, the second peak at x=5 vanishes. Still curious but out of ideas.
Vedere anche
Categorie
Scopri di più su Loops and Conditional Statements in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!