Matlab:从parfor循环打印进度 [英] Matlab: Print progress from parfor loop
问题描述
我在Matlab中运行了许多长时间的仿真,通常需要几分钟到几小时,因此为了加快速度,我决定使用parfor
循环同时运行仿真.
I run a lot of long simulations in Matlab, typically taking from a couple of minutes to a couple of hours, so to speed things up I decided to run the simulations simultaneously using a parfor
loop.
arglist = [arg1, arg2, arg3, arg4];
parfor ii = 1:size(arglist, 2)
myfun(arglist(ii));
end
一切正常,除了一件事:进度打印.由于每次模拟都花费大量时间,因此我通常使用类似的方式打印进度
Everything worked just fine, except for one thing: the progress printing. Since each simulation takes a lot of time, I usually print progress using something like
prevlength = 0;
for ii = 1:tot_iter
% Some calculations here
msg = sprintf('Working on %d of %d, %.2f percent done', ii, tot_iter, ii/tot_iter);
fprintf(repmat('\b', 1, prevlength))
fprintf(msg);
prevlength = numel(msg);
end
但是,正如可以预期的那样,在parfor
循环中执行此操作时,您会感到混乱.
but, as could be expected, when doing this inside a parfor
loop, you get chaos.
我在Google上进行了大量搜索以寻求解决方案,并找到了许多诸如
I have googled a lot in search of a solution and have found a bunch of "parfor progress printers" like this one. However, all of them print the progress of the entire parfor
loop instead of showing how far each of the individual iterations have come. Since I only have about 4-8 iterations in the parfor
loop, but each iteration takes about an hour, this approach isn't very helpful to me.
对我来说,理想的解决方案是像这样的东西
The ideal solution for me would be something that looks like this
Working on 127 of 10000, 1.27 percent done
Working on 259 of 10000, 2.59 percent done
Working on 3895 of 10000, 38.95 percent done
Working on 1347 of 10000, 13.47 percent done
也就是说,每个模拟只有一行显示其运行了多远.我不确定这是否完全可行,至少我无法想象有任何方法可以做到这一点.
that is, each simulation gets one line showing how far it has run. I'm not sure though if this is possible at all, I can at least not imagine any way to do this.
另一种方式是做这样的事情
Another way would be to do something like this
Sim 1: 1.27% Sim 2: 2.59% Sim 3: 38.95% Sim 4: 13.47%
,即在同一行上显示所有进度.为此,您需要跟踪每个模拟在行上要写的位置,并在该位置写,而不能擦除其他进度.我不知道该怎么做,这可能吗?
that is, show all the progresses on the same line. To do this, you would need to keep track of what position on the line each simulation is to write on and write there, without erasing the other progresses. I can't figure out how this would be done, is this possible to do?
如果有我未曾想到的其他解决方案(显示每个迭代的进度),我很乐意听到.
If there is some other solution to my problem (showing the progress of each individual iteration) that I haven't thought of, I'd be happy to hear about it.
因为这是我第一次在这里提出问题,所以很可能我错过了一些事情.如果是这样,请在下面随意评论.
Since this is the first time I ask a question here on SO it is quite possible that there is something that I have missed; if so, please feel free to comment below.
在收到此答案后,我认为我应该分享自己用它来解决问题的方式,因为我没有如果其他人遇到相同的问题,请完全按照答案中的说明使用它.
After receiving this answer, I thought that I should share how I used it to solve my problem since I didn't use it exactly as in the answer, in case someone else encounters the same problem.
这是一个小型测试程序,其结构与我的程序基本相同,利用了答案中提到的进度条(parfor_progress
):
Here is a small test program with basically the same structure as my program, making use of the progress bar (parfor_progress
) mentioned in the answer:
function parfor_progress_test()
cpus = feature('numCores');
matlabpool('open', cpus);
cleaner = onCleanup(@mycleaner);
args = [1000, 1000, 1000, 1000];
m = sum(args);
parfor_progress(m);
parfor ii = 1:size(args,2)
my_fun(args(ii));
end
parfor_progress(0);
end
function my_fun(N)
for ii = 1:N
pause(rand*0.01);
parfor_progress;
end
end
function mycleaner
matlabpool close;
fclose all;
end
推荐答案
简单进度栏
类似进度条的操作可以与此类似...
Simple Progress Bar
Something like a progress bar could be done similar to this...
在parfor
循环之前:
fprintf('Progress:\n');
fprintf(['\n' repmat('.',1,m) '\n\n']);
在循环中:
fprintf('\b|\n');
在这里,我们有m
是迭代的总数,.
是迭代的总数,而|
是已完成的迭代数. \n
确保在parfor
循环中打印字符.
Here we have m
is the total number of iterations, the .
shows the total number of iterations and |
shows the number of iterations completed. The \n
makes sure the characters are printed in the parfor
loop.
否则,您可以尝试以下操作: http://www.mathworks.com/matlabcentral/fileexchange/32101-progress-monitor--progress-bar--that-works-with-parfor
Otherwise you could try this: http://www.mathworks.com/matlabcentral/fileexchange/32101-progress-monitor--progress-bar--that-works-with-parfor
它将显示进度条和完成百分比,但可以轻松地修改为仅包含百分比完成或进度栏.
It will display a progress bar and percentage completion but can be easily modified to just include the percentage completion or progress bar.
此函数在每次迭代时将一个字符修改到一个文件,然后读取写入该文件的字符数,以指示已完成的迭代数. parfor
允许使用此文件访问方法.
This function amends a character to a file on every iteration and then reads the number of characters written to that file which indicates the number of iterations completed. This file accessing method is allowed in parfor
's.
假设您以某种方式正确地将以上内容添加到了您的MATLAB路径,则可以使用以下内容:
Assuming you correctly add the above to your MATLAB path somehow, you can then use the following:
arglist = [arg1, arg2, arg3, arg4];
parfor_progress(size(arglist, 2)); % Set the total number of iterations
parfor ii = 1:size(arglist, 2)
myfun(arglist(ii));
parfor_progress; % Increment the progress counter
end
parfor_progress(0); % Reset the progress counter
完成时间和完成百分比
还有一个名为showTimeToCompletion()
的功能,可从以下网址获得: https://www.soundzones.com/software/sound-zone-tools/
Time to Completion and Percentage Completion
There is also a function called showTimeToCompletion()
which is available from: https://www.soundzones.com/software/sound-zone-tools/
并与parfor_progress
一起使用.此功能使您可以打印parfor循环(或与此有关的任何循环)进度的详细摘要,其中包括开始时间,运行时间长度,估计的完成时间和完成百分比.它巧妙地使用了\b
(退格)字符,因此命令窗口不会被文本淹没.尽管不是严格意义上的" bar "进度,但它可能会提供更多信息.
and works alongside parfor_progress
. This function allows you to print a detailed summary of the progress of a parfor loop (or any loop for that matter) which contains the start time, length of time running, estimated finish time and percentage completion. It makes smart use of the \b
(backspace) character so that the command window isn't flooded with text. Although not strictly a progress 'bar' it is perhaps more informative.
函数文件标题中的第三个示例
The third example in the header of the function file,
fprintf('\t Completion: ');
showTimeToCompletion; startTime=tic;
len=1e2;
p = parfor_progress( len );
parfor i = 1:len
pause(1);
p = parfor_progress;
showTimeToCompletion( p/100, [], [], startTime );
end
将以下内容输出到命令窗口:
outputs the following to the command window:
Completion: 31.00%
Remaining: 00:00:23
Total: 00:00:33
Expected Finish: 3:30:07PM 14-Nov-2017
用于估计正在运行的仿真的完成情况,尤其是可能要花费数小时或数天的仿真.
Useful for estimating the completion of a running simulation, especially one that may take hours or days.
这篇关于Matlab:从parfor循环打印进度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!