一般信息
很多功能隱式多線程內(nèi)置,使.parfor
當(dāng)使用這些函數(shù)時(shí),循環(huán)效率不會(huì)比串行函數(shù)高。for
循環(huán),因?yàn)樗械暮诵亩家呀?jīng)被使用了。parfor
在這種情況下實(shí)際上是一種損害,因?yàn)樗哂蟹峙溟_(kāi)銷(xiāo),同時(shí)與您試圖使用的函數(shù)是并行的。
當(dāng)不使用隱式多線程函數(shù)之一時(shí)parfor
基本上建議在兩種情況下進(jìn)行迭代:循環(huán)中的大量迭代(例如,1e10
),或者每次迭代需要很長(zhǎng)的時(shí)間(例如,eig(magic(1e4))
)。在第二種情況下,您可能需要考慮使用spmd
(比parfor
根據(jù)我的經(jīng)驗(yàn))。原因parfor
比for
循環(huán)用于短期或快速迭代是正確管理所有工作人員所需的開(kāi)銷(xiāo),而不僅僅是進(jìn)行計(jì)算。
查帳這個(gè)問(wèn)題有關(guān)在不同員工之間拆分?jǐn)?shù)據(jù)的信息。
標(biāo)桿
電碼
請(qǐng)考慮下面的示例來(lái)查看for
相對(duì)于parfor
..如果您還沒(méi)有打開(kāi)并行池,那么首先打開(kāi)它:
gcp; % Opens a parallel pool using your current settings
然后執(zhí)行幾個(gè)大循環(huán):
n = 1000; % Iteration numberEigenValues = cell(n,1); % Prepare to store the dataTime = zeros(n,1);for ii = 1:ntic
EigenValues{ii,1} = eig(magic(1e3)); % Might want to lower the magic if it takes too longTime(ii,1) = toc; % Collect time after each iterationendfigure; % Create a plot of resultsplot(1:n,t)title 'Time per iteration'ylabel 'Time [s]'xlabel 'Iteration number[-]';
然后用同樣的方法parfor
而不是for
..您會(huì)注意到,每次迭代的平均時(shí)間會(huì)增加(我的情況是0.27s到0.39s)。但是要意識(shí)到parfor
使用所有可用的工人,因此總時(shí)間(sum(Time)
)必須除以計(jì)算機(jī)中的核數(shù)。因此,就我的情況而言,總時(shí)間從大約270秒下降到了49秒,因?yàn)槲矣幸粋€(gè)八進(jìn)制處理器。
因此,當(dāng)每次單獨(dú)迭代的時(shí)間增加時(shí),使用parfor
關(guān)于使用for
,總時(shí)間大大減少了。
結(jié)果
這張照片顯示了測(cè)試的結(jié)果,因?yàn)槲抑皇窃谖业募彝C上運(yùn)行它。我用n=1000
和eig(500)
我的電腦有一個(gè)i5-750 2.66GHz處理器,有四個(gè)核,運(yùn)行MATLABR201a。正如您所看到的,并行測(cè)試的平均值在0.29s左右徘徊,并且有很大的擴(kuò)展,而串行代碼在0.24s左右相當(dāng)穩(wěn)定。然而,總時(shí)間從234秒下降到72秒,速度提高了3.25倍。這并不完全是4的原因是內(nèi)存開(kāi)銷(xiāo),如每次迭代所需的額外時(shí)間所表示的那樣。內(nèi)存開(kāi)銷(xiāo)是由于MATLAB必須檢查每個(gè)內(nèi)核正在做什么,并確保每個(gè)循環(huán)迭代只執(zhí)行一次,并且數(shù)據(jù)被放入正確的存儲(chǔ)位置。