classdef testcls
methods
function sayhello(~)
disp('Hello! ')
end
end
end
和,如果我現在調用該方法在parfor
如下
A = testcls;
parfor ii = 1:4
A.sayhello()
end
Mlint告訴我一個性能問題在迴路中使用A
:
The entire array or structure 'obj' is a broadcast variable. This might result in unnecessary communication overhead.
而且我可以suppr ESS此消息通過使用匿名函數:
A = testcls;
f = @A.sayhello;
parfor ii = 1:4
f()
end
但我的問題是,這樣做幫助,反正速度?有沒有更好的方法來調用parfor
中的方法?
那麼,如果我想設置函數的輸入/輸出參數,那麼情況會變得更復雜嗎?
classdef testcls
methods
function [out1,out2] = sayhello(~,n)
out1 = (['Hello! ', num2str(n)]);
out2 = n;
end
end
end
A = testcls;
f = @A.sayhello;
[a,b] = deal(cell(4,1));
parfor ii = 1:4
[a{ii},b{ii}] = feval(f,ii);
end
編輯:
我觀察相關的內存複製操作顯著資源消耗。基本上,作業調度員將爲每個工人創建一個相同的對象,包括所有修改後的屬性。
f = @A.sayhello;
使用不會將Matlab從memcpy整個對象存儲到每個工作人員,即使該方法本身不調用或存儲任何類屬性。
我認爲這是確保透明度的方法。然而,當數據量巨大時,這將成爲頭痛的一大難題。
有沒有一種方法,而不是孤立所需的功能到一個獨立的基於文件的功能,包裝sayhello
在對象中,將不會調用整個對象的複製?
編輯:感謝@gnovice提示性答案。我曾經爲了與靜態方法,parfor
非靜態方法比較parfor
做了一個試驗案例,並使用arrayfun
串行執行。
測試用例1:parfor
與非靜態方法(對照)
如可在存儲器使用記錄可以看出,單個對象testcls
的創建使用〜700MB RAM,由指示標籤1
,隨後是一個clear
命令標記爲2
和parfor
環以上標籤3
運行。 parfor
的峯值使用量約爲單個對象的4倍,而游泳池有4名工人。
測試用例2:parfor
與靜態方法
試驗程序完成並以同樣的方式進行標記。從這些證據可以得出結論,只有將方法設爲靜態並不能防止parpool爲所有工作人員產生相同的對象。
測試用例3:使用arrayfun
由於arrayfun
串行評價進行非順序串行批次評價,這裏沒有理由arrayfun
使用比需要由單個線程更多的存儲器。因此證據。
示例代碼:
classdef testcls
properties
D
end
methods (Static = false)
function [out1,out2] = sayhello(~,n)
out1 = (['Hello! ', num2str(n)]);
out2 = n;
end
end
methods
function obj = testcls(~)
obj.D = rand(1e8,1);
end
end
end
要運行測試,使用這個腳本:
clear;clc;close all
A = testcls;
f = @A.sayhello;
parfor ii = 1:4
feval(f,ii)
end
您可以用arrayfun
代替parfor
串行驗證。
你最後的示例代碼給出了錯誤:「切片變量f不能引用函數處理」 - 你必須使用'feval(F,II)'代替([見這裏](https://www.mathworks.com/help/distcomp/objects-and-handles-in-parfor-loops.html)) – whrrgarbl
@ whrrgarbl哇你是對的。我自己的代碼沒有任何爭論,但我認爲它可以與一個工作。我編輯我的代碼到最簡單的情況。 – Yvon