Multi-Dim array vs (Reshape and 2D array)

2 ビュー (過去 30 日間)
Sebastian
Sebastian 2012 年 7 月 1 日
I want to test if is more convenient keep my data in a 2D matrix (in each column I keep differents kinds of information in sorted way) or use multi-dim matrix: m_A(d1*d2,d3) or m_A(d1,d2,d3). If I call a function that have argument m_B(d1,d2), I should send reshape(m_A(:,i3),d1,d3) or m_A(:,:,i3).
My test function is:
function f_ReshapeVsMultiArray
nPrueba = 10000;
a = 200;
m_MultiArray = rand(a,a,nPrueba);
m_Array = reshape(m_MultiArray,[],nPrueba);
disp('1')
tic
for iPrueba = 1:nPrueba
m_MultiArray(:,:,iPrueba) = f_CalcPorcMat(m_MultiArray(:,:,iPrueba));
end
toc
disp('2')
tic
for iPrueba = 1:nPrueba
m_Array(:,iPrueba) = reshape(f_CalcPorcMat(reshape(m_Array(:,iPrueba),a,a)),[],1);
end
toc
disp('3')
tic
nVal = a*a;
m_Ind = 1:nVal;
for iPrueba = 1:nPrueba
m_Array(m_Ind,iPrueba) = reshape(f_CalcPorcMat(reshape(m_Array(m_Ind,iPrueba),a,a)),[],1);
end
toc
disp('4')
tic
for iPrueba = 1:nPrueba
m_ArrayCuadr = m_MultiArray(:,:,iPrueba);
m_ArrayCuadr = f_CalcPorcMat(m_ArrayCuadr);
m_MultiArray(:,:,iPrueba) = m_ArrayCuadr;
end
toc
disp('5')
tic
for iPrueba = 1:nPrueba
m_ArrayCuadr = reshape(m_Array(:,iPrueba),a,a);
m_ArrayCuadr = f_CalcPorcMat(m_ArrayCuadr);
m_Array(:,iPrueba) = reshape(m_ArrayCuadr,[],1);
end
toc
disp('6')
tic
for iPrueba = 1:nPrueba
m_ArrayCuadr = reshape(m_Array(:,iPrueba),a,a);
m_ArrayCuadr = f_CalcPorcMat(m_ArrayCuadr);
m_Array(:,iPrueba) = m_ArrayCuadr(:);
end
toc
disp('7')
tic
nVal = a*a;
m_Ind = 1:nVal;
for iPrueba = 1:nPrueba
m_ArrayCuadr = reshape(m_Array(m_Ind,iPrueba),a,a);
m_ArrayCuadr = f_CalcPorcMat(m_ArrayCuadr);
m_Array(m_Ind,iPrueba) = m_ArrayCuadr(:);
end
toc
disp('8')
tic
for iPrueba = 1:nPrueba
m_ArrayCuadr = m_Array(:,iPrueba);
m_ArrayCuadr = f_CalcPorcMatReshape(m_ArrayCuadr,a);
m_Array(:,iPrueba) = m_ArrayCuadr;
end
toc
end
function m_Mat = f_CalcPorcMat(m_Mat)
m_Mat = m_Mat*m_Mat;
end
function m_Mat = f_CalcPorcMatReshape(m_Mat,a)
m_Mat = reshape(m_Mat,a,a);
m_Mat = m_Mat*m_Mat;
m_Mat = m_Mat(:);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
With a = 100:
1: Elapsed time is 2.438622 seconds.
2: Elapsed time is 2.042828 seconds.
3: Elapsed time is 4.672457 seconds.
4: Elapsed time is 2.148157 seconds.
5: Elapsed time is 2.048681 seconds.
6: Elapsed time is 2.011032 seconds.
7: Elapsed time is 3.972383 seconds.
8: Elapsed time is 2.024055 seconds.
With a = 200:
1: Elapsed time is 9.004146 seconds.
2: Elapsed time is 7.572500 seconds.
3: Elapsed time is 15.502879 seconds.
4: Elapsed time is 7.754266 seconds.
5: Elapsed time is 7.577100 seconds.
6: Elapsed time is 7.523504 seconds.
7: Elapsed time is 14.759984 seconds.
8: Elapsed time is 7.642342 seconds.
My questions:
- Why case (1), multi-dim array, is more slow that case (2), reshape and 2D matrix?
- Why case (3), is so more slow that case (2)? The only change is using indexing with matrix vs colon operator :.
- Why case (1) is more slow that case (4), but not with case (2) and (5)? The only differences is using temporary variables and more code lines.
Thanks by any tips o information.
PS: I changed by "Multi-Dim array", how is indicated by Jan Simon.

採用された回答

Jan
Jan 2012 年 7 月 2 日
Your case 1 - I omit the loop code:
m_MultiArray(:,:,iPrueba) = f_CalcPorcMat(m_MultiArray(:,:,iPrueba));
In each iteration Matlab has to copy 2 dimensions (both nmarked by ':') and it uses 2 loops internally.
Your case 2:
m_Array(:,iPrueba) = reshape(f_CalcPorcMat(reshape(m_Array(:,iPrueba),a,a)),[],1);
needs one loop only internally for the copy.
Your case 3:
nVal = a*a;
m_Ind = 1:nVal;
for iPrueba = 1:nPrueba
m_Array(m_Ind, iPrueba) = reshape(f_CalcPorcMat( ...
reshape(m_Array(m_Ind,iPrueba),a,a)),[],1);
end
This has the overhead for 2 repmat calls, but it is much more expensive to replace the colon operator ':' by an explicit index vector. The latter checks for each element, if it is inside the limits, while the following does this test for the first and the last element only:
m_Array(1:nVal, iPrueba) = reshape(f_CalcPorcMat( ...
reshape(m_Array(1:nVal, iPrueba),a,a)),[],1);
Then Matlab can use a fast memcpy procedure to copy large blocks of memory, which is most likely supported by SSE instructions. If the index vector is calculated before the copy, such optimizations are not possible, because Matlab looses the information that the index vector is a contiguous block.
The advantage of case 4 is not clear to me. I guess that the JIT-acceleration uses the same memory block for storing the temporary array, while case 1 allocates a new block in each iteration. This could be tested using format('debug').
Btw, "multiarray" is no defined expression in Matlab, such that I'd prefer "multi-dim array". Especially "multiarray matrix" is confusing.
  1 件のコメント
Sebastian
Sebastian 2012 年 7 月 2 日
I test with:
m_Array(1:nVal,iPrueba) = reshape(f_CalcPorcMat(...
reshape(m_Array(1:nVal,iPrueba),a,a)),[],1);
a = 100;
9: Elapsed time is 2.813437 seconds.
a = 200;
9: Elapsed time is 10.373823 seconds.
Case (9) is better time that case (3), but yet isn't equal to case (2).
Why MatLab don't have a optimization (one "for") for indexing multi-dim array, when is used colon operator ":" two o more times, if all array are column-wise?

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeMatrix Indexing についてさらに検索

製品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by