1

DEM (4800x6000) 内の各ピクセルの特定の属性を計算しようとしている大きなループがあります。26 個のフィールドを持つ構造体を出力するすべての計算をベクトル化した関数 demPHV を呼び出しています。私は 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 つのオプションのどちらかが他方よりも高速であると思いますか?
  2. parfor では、元のループの 2 番目の部分を含めることができません。

    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。これは恐ろしくメモリの非効率的な使用のようです...何か良い提案はありますか? すべてを網羅したことを願っています。ご覧いただきありがとうございます。

4

1 に答える 1

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  

編集:これは不器用かもしれませんが、変数を再割り当てするために次のように機能します。より洗練された「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
于 2012-10-28T21:14:48.907 に答える