1

次の機能を実行する for ループがあります。

M x 8 行列を取得し、次のようにします。

  1. それをサイズ 512 要素のブロックに分割します (つまり、行列の X 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

500 万の要素でこのループを実行すると、1 時間以上かかります。できるだけ速くする必要があります(秒単位)。このループはベクトル化できますか?

4

4 に答える 4

4

関数の説明に基づいて、私が思いついたのは次のとおりです。

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

この図は、上記を理解するのに役立ちます。

ダイアグラム

于 2010-02-22T19:56:52.207 に答える
3

ベクトル化が役立つ場合とそうでない場合があります。ボトルネックがどこにあるかを知ることは役に立ちます。ここで概説されているように、プロファイラーを使用します。

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

于 2010-02-22T16:16:22.927 に答える
0

何をしようとしているのかを教えていただければ幸いです (私の推測では、動的システムでのシミュレーションですが、わかりにくいです)。

はい、もちろんベクトル化できます。各ブロックは実際には 4 つのサブブロックです。あなたの(非常に非標準的な)インデックスを使用して:

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

ベクトル化のすべてのカーネル/スレッド/呼び出し元は、次のことを行う必要があります。

i = threadIdx は 0 ~ 127 です temp = data[1 + i] data[1 + i] = data[385+i] data[385 + i] = data[257+i] data[257 + i] = data [129+i] データ[129 + i] = 温度

もちろん、ベクトル化だけでなく、ブロックでも並列化する必要があります。

于 2010-02-22T14:04:14.610 に答える
0

もう一度、私の質問を解決する方法についてアイデアを提供してくれた Amro に感謝したいと思います。質問で自分自身を明確にして申し訳ありません。

これが私の問題に対する私の解決策です:

%#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
于 2010-02-23T12:12:41.180 に答える