Matlab:从parfor循环打印进度

 yiqing020308 发布于 2023-01-16 12:59

我在Matlab中运行了很多长时间的模拟,通常需要几分钟到几个小时,所以为了加快速度,我决定使用parfor循环同时运行模拟.

arglist = [arg1, arg2, arg3, arg4];

parfor ii = 1:size(arglist, 2)
    myfun(arglist(ii));
end

一切都运作得很好,除了一件事:进步印刷.由于每次模拟都需要花费很多时间,因此我通常使用类似的东西来打印进度

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循环中执行此操作时,会出现混乱.

我用Google搜索了很多寻找一个解决方案,并已发现了一堆"PARFOR进步打印机"像这一个.但是,所有这些都打印整个parfor循环的进度,而不是显示每个迭代的进度.由于我在parfor循环中只有大约4-8次迭代,但每次迭代大约需要一个小时,这种方法对我来说并不是很有帮助.

对我来说理想的解决方案就是这样

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

也就是说,每个模拟得到一行显示它运行了多远.我不确定如果这是可能的,我至少不能想象有任何办法这样做.

另一种方法是做这样的事情

Sim 1: 1.27%    Sim 2: 2.59%    Sim 3: 38.95%   Sim 4: 13.47%

也就是说,显示同一行的所有进展.要做到这一点,你需要跟踪每个模拟要在线上写入和写入的位置,而不删除其他进程.我无法弄清楚如何做到这一点,这可能吗?

如果我的问题有其他解决方案(显示每个单独迭代的进度),我没有想到,我很乐意听到它.

因为这是我第一次在这里问一个问题,所以很可能有一些我错过的东西; 如果是这样,请随时在下面发表评论.

编辑

收到这个答案之后,我认为我应该分享我是如何使用它来解决我的问题的,因为我没有像答案那样完全使用它,以防其他人遇到同样的问题.

这是一个小程序,与我的程序结构基本相同,使用parfor_progress答案中提到的进度条():

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

JacobD.. 16

简单的进度栏

类似于进度条的东西可以像这样做...

parfor循环之前:

fprintf('Progress:\n');
fprintf(['\n' repmat('.',1,m) '\n\n']);

并在循环期间:

fprintf('\b|\n');

这里我们有m迭代的总数,.显示了迭代的总数,并|显示了完成的迭代次数.在\n确保该字符的打印parfor循环.

进度条和完成百分比

否则你可以试试这个:http://www.mathworks.com/matlabcentral/fileexchange/32101-progress-monitor--progress-bar--that-works-with-parfor

它将显示进度条和完成百分比,但可以轻松修改为仅包括完成百分比或进度条.

此函数在每次迭代时将字符修改为文件,然后读取写入该文件的字符数,表示完成的迭代次数.这个文件访问方法是允许parfor的.

假设您以某种方式正确地将上述内容添加到MATLAB路径中,则可以使用以下内容:

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/

并与之合作parfor_progress.此功能允许您打印parfor循环(或任何循环)的详细摘要,其中包含开始时间,运行时间长度,估计完成时间和完成百分比.它巧妙地使用了\b(退格)字符,因此命令窗口不会充满文本.虽然不是严格意义上的进步" 酒吧 ",但它可能更具信息性.

函数文件头中的第三个例子,

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

将以下内容输出到命令窗口:

     Completion: 31.00%
      Remaining: 00:00:23
          Total: 00:00:33
Expected Finish: 3:30:07PM  14-Nov-2017

用于估计正在运行的模拟的完成,尤其是可能需要数小时或数天的模拟.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有