Можно ли векторизовать следующий цикл? - PullRequest
1 голос
/ 22 февраля 2010

У меня есть цикл for, который выполняет следующую функцию:

Возьмите матрицу М на 8 и:

  1. Разделить его на блоки размером 512 элементов (что означает X на 8 матрицы == 512, а количество элементов может составлять 128,256,512,1024,2048)
  2. Преобразуйте блок в матрицу 1 на 512 (количество элементов).
  3. Возьмите последнюю 1/4 матрицы и поместите ее впереди,
    например Data = [Data(1,385:512),Data(1,1:384)];

Вот мой код:

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

Выполнение этого цикла с 5 миллионами элементов займет более 1 часа. Мне нужно, чтобы это было как можно быстрее (в секундах). Может ли этот цикл быть векторизованным?

Ответы [ 4 ]

4 голосов
/ 22 февраля 2010

На основании описания вашей функции вот что я придумал:

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(:);

эта диаграмма может помочь в понимании выше:

diagram

3 голосов
/ 22 февраля 2010

Векторизация может или не может помочь. Что поможет, так это знание , где узкое место. Используйте профилировщик, как указано здесь:

http://blogs.mathworks.com/videos/2006/10/19/profiler-to-find-code-bottlenecks/

0 голосов
/ 23 февраля 2010

Еще раз я хотел бы поблагодарить Амро за то, что он дал мне идею, как решить мой вопрос. Извините за то, что я не прояснил себя в вопросе.

Вот мое решение моей проблемы:

%#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
0 голосов
/ 22 февраля 2010

Было бы неплохо, если бы вы рассказали, что вы пытаетесь сделать (я думаю, это какая-то симуляция в динамических системах, но трудно сказать).

да, конечно, это может быть векторизовано: каждый из ваших блоков - это фактически четыре субблока; используя ваши (крайне нестандартные) индексы:

1 ... 128, 129 ... 256, 257 ... 384, 385 ... 512

Каждое ядро ​​/ поток / то, что вы когда-либо называете при векторизации, должно делать следующее:

i = threadIdx находится между 0 и 127 temp = data [1 + i] данные [1 + i] = данные [385 + i] данные [385 + i] = данные [257 + i] данные [257 + i] = данные [129 + i] данные [129 + i] = температура

Конечно, вы должны также распараллеливать блоки, а не только векторизовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...