la boucle suivante peut être vectorisé?
-
22-09-2019 - |
Question
I ai un pour-boucle qui remplit la fonction suivante:
Il suffit de M par matrice et 8:
- diviser en blocs de taille 512 éléments (sens X par 8 de la matrice == 512, et le nombre d'éléments peut être 128,256,512,1024,2048)
- refaçonner le bloc en 1 par 512 (nombre d'éléments) matrice.
- Prenez le dernier quart de la matrice et le mettre en avant,
par exemple.Data = [Data(1,385:512),Data(1,1:384)];
Ce qui suit est mon code:
for i = 1 : NumOfBlock
if i == 1
Header = tempHeader(1:RowNeeded,:);
Header = reshape(Header,1,BlockSize); %BS
Header = [Header(1,385:512),Header(1,1:384)]; %CP
Data = tempData(1:RowNeeded,:);
Data = reshape(Data,1,BlockSize); %BS
Data = [Data(1,385:512),Data(1,1:384)]; %CP
start = RowNeeded + 1;
end1 = RowNeeded * 2;
else
temp = tempData(start:end1,:);
temp = reshape(temp,1,BlockSize); %BS
temp = [temp(1,385:512),temp(1,1:384)]; %CP
Data = [Data, temp];
end
if i <= 127 & i > 1
temp = tempHeader(start:end1,:);
temp = reshape(temp,1,BlockSize); %BS
temp = [temp(1,385:512),temp(1,1:384)]; %CP
Header = [Header, temp];
end
start = end1 + 1;
end1=end1 + RowNeeded;
end
L'exécution de cette boucle avec 5 millions élément prendra plus de 1 heure. Je besoin d'être aussi rapide que possible (en sec). Est-ce cette boucle peut être vectorisé?
La solution 4
Encore une fois, je voudrais remercier Amro pour me donner une idée sur la façon de résoudre ma question. Désolé de ne pas me faire clairement dans la question.
Voici ma solution à mon problème:
%#BS CDMA, Block size 128,512,1024,2048
BlockSize = 512;
RowNeeded = BlockSize / 8;
TotalRows = size(tempData);
TotalRows = TotalRows(1,1);
NumOfBlock = TotalRows / RowNeeded;
CPSize = BlockSize / 4;
%#spilt into blocks
Header = reshape(tempHeader',[RowNeeded,8, 128]);
Data = reshape(tempData',[RowNeeded,8, NumOfBlock]);
clear tempData tempHeader;
%#block spread & cyclic prefix
K = zeros([1,BlockSize,128],'single');
L = zeros([1,BlockSize,NumOfBlock],'single');
for i = 1:NumOfBlock
if i <= 128
K(:,:,i) = reshape(Header(:,:,i),[1,BlockSize]);
K(:,:,i) = [K((CPSize*3)+1:BlockSize),K(1:CPSize*3)];
end
L(:,:,i) = reshape(Data(:,:,i),[1,BlockSize]);
L(:,:,i) = [L((CPSize*3)+1:BlockSize),L(1:CPSize*3)];
end
Autres conseils
D'après votre description de fonction, voici ce que je suis venu avec:
M = 320; %# M must be divisble by (numberOfElements/8)
A = rand(M,8); %# input matrix
num = 512; %# numberOfElements
rows = num/8; %# rows needed
%# equivalent to taking the last 1/4 and putting it in front
A = [A(:,7:8) A(:,1:6)];
%# break the matrix in blocks of size (x-by-8==512) into the third dimension
B = permute(reshape(A',[8 rows M/rows]),[2 1 3]);
%'# linearize everything
B = B(:);
ce diagramme peut aider à comprendre ce qui précède:
Vectorisation peut ou ne peut pas aider. Qu'est-ce qui est Omniscient aider à où le goulot d'étranglement est. Utilisez le profileur comme indiqué ici:
http: // blogs. mathworks.com/videos/2006/10/19/profiler-to-find-code-bottlenecks/
Ce serait bien si vous dire ce que vous essayez de faire (je suppose une simulation dans les systèmes dynamiques, mais il est difficile de dire).
oui, bien sûr, il peut être vectorisé: chacun de vos blocs est en fait quatre blocs sous; en utilisant vos indices (standard extrêmement non):
1 ... 128, 129 ... 256, 257 ... 384, 385 ... 512
Chaque noyau / fil / what-you-jamais-appelez-il de la vectorisation doit faire ce qui suit:
i = threadIdx est compris entre 0 et 127 temp = données [1 + i] données [1 + i] = données [385 + i] données [385 + i] = données [257 + i] données [257 + i] = données [129 + i] données [129 + i] = Temp
Vous devez bien sûr aussi paralléliser sur des blocs, non seulement vectoriser.