2012-10-27 82 views
1

我有一個大循環,我試圖計算DEM(4800x6000)中每個像素的某些屬性。我正在調用一個函數demPHV,在這個函數中,我已經將所有計算結果向量化爲輸出具有26個字段的結構。我有4個內核,但也可以訪問多核羣集。我想加快運行這個周的時間。並行化一個大循環

Z是這個例子的dem。 R是spatialref對象(例如,一個矢量)。 latlim和lonlim是美國西部海岸線的緯度和長度的矢量(在這個例子中由雙組成)。 例如:

Z=rand(48,60); 
R=makerefmat(120,40,.5,.5) 
latlim=[40:60]'; 
lonlim=[136:(143-136)/(length(latlim)-1):143]'; 

然後我原來的循環:

for col=11:size(Z,2)-11 
    for row=11:size(Z,1)-11 
     dpv=demPHV(Z,R,row,col,latlim,lonlim) 

    fn=fieldnames(dpv); 
    for k=1:length(fieldnames(dpv)) 
     DEM_PHV.(fn{k}).{row,col}=dpv.(fn{k}); 
    end 
end 

循環並行化:

選項1:

[rows, cols] = meshgrid(12:(size(Z,1)-12), 12:(size(Z,2)-12)); 
inds = sub2ind(size(Z), rows, cols); 
inds = inds(:)'; 
parfor i=inds(1):inds(end) 
     dpv=demPHV(Z,R,i,latlim,lonlim) 
end 

這包括[r,c]=ind2sub(size(Z),i)在使用該功能功能demPHV。

選項2:

parfor col=11:size(Z,2)-11 
    for row=11:size(Z,1)-11 
     dpv=demPHV(Z,R,row,col,latlim,lonlim) 
    end 
end 

PARFOR需要連續的整數,因此其中的一些變化。我必須排除鄰接的11行和列,因爲我的函數使用周圍的像素來計算一些屬性。

所以,我的問題:

  1. 你所期望的任一兩個選項是比其他快?
  2. PARFOR不允許我,包括我的原始循環的第二部分:在W¯¯

    fn=fieldnames(dpv);

    for k=1:length(fieldnames(dpv))

    DEM_PHV.(fn{k}).{row,col}=dpv.(fn{k});

    end

我將輸出結構分配給另一個變量。最終目標是讓變量DEM_PHV具有我需要的每個屬性的字段,並且每個字段都是矩陣大小(Z),其中每個單元格都是該屬性的對應值。我嘗試讓我的函數輸出矩陣的正確單元格中的值,但隨後我得到的矩陣大小(Z)爲[],除了位置row,col處的值。這似乎是一個可怕的低效率的記憶使用...有什麼更好的建議?我希望我涵蓋了一切。 感謝您的期待!

回答

0

我得到了下面的代碼來將每個函數結果存儲到一個結構數組中。可能有更好的方法,因爲現在我需要從結構中的每個字段中提取每個值到它自己的矩陣中。

有沒有人有建議創建類似於:DEM_PHV = struct('field1',[dPHV{:}.field1],'field2',[dPHV{:}.field2])其中每個字段中的每個矩陣是size(Z)。矩陣中的單元格將包含單個值或一對,如[lat,long]。

dPHV=cell(110,110); 
parfor col=11:110%size(Z,2)-11 
    for row = 11:110%size(Z,1)-11 
     pixel_attributes=demPHV(Z,R,row,col,latlim,lonlim); %function produces structure of variables, each iteration is another pixel 
     dPHV{row,col}=structfun(@(x) x,pixel_attributes,'UniformOutput',false) 
    end 
end 

編輯:因爲這可能是kludgey,下面的工作重新分配變量。我很樂意爲閃爍的'MATLAB'方式提供建議。

% find all field names and get size of output 
fn=fieldnames(dPHV{11,11}); 
[I, J]=size(dPHV); 

%initialize final output 
for f=1:numel(fn) 
    DEM_PHV.(fn{f})=cell(size(dPHV)); 
end 
% loops through datastructure to populate new fields 
for i=11:I-11 
    for j=11:J-11 
     for f=1:numel(fn) 
      DEM_PHV.(fn{f}){i,j}=dPHV{i,j}.(fn{f}); 
     end 
    end 
end