Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何知道Matlab中parfor循环中还剩下多少次迭代?_Matlab_For Loop_Parallel Processing - Fatal编程技术网

如何知道Matlab中parfor循环中还剩下多少次迭代?

如何知道Matlab中parfor循环中还剩下多少次迭代?,matlab,for-loop,parallel-processing,Matlab,For Loop,Parallel Processing,我正在Matlab中运行一个parfor循环,这需要很多时间,我想知道还有多少次迭代。我怎样才能得到这些信息呢?我不相信你能直接从MATLAB中得到这些信息,除非每次迭代都打印一些东西,并手工计算这些行 要了解原因,请回想一下每个parfor迭代都在其自己的工作区中执行:虽然在循环中增加计数器是合法的,但访问其“当前”值是不合法的(因为在循环完成之前,该值实际上不存在)。此外,parfor构造不保证任何特定的执行顺序,因此打印迭代器值没有帮助 cnt = 0; parfor i=1:n

我正在Matlab中运行一个parfor循环,这需要很多时间,我想知道还有多少次迭代。我怎样才能得到这些信息呢?

我不相信你能直接从MATLAB中得到这些信息,除非每次迭代都打印一些东西,并手工计算这些行

要了解原因,请回想一下每个
parfor
迭代都在其自己的工作区中执行:虽然在循环中增加计数器是合法的,但访问其“当前”值是不合法的(因为在循环完成之前,该值实际上不存在)。此外,
parfor
构造不保证任何特定的执行顺序,因此打印迭代器值没有帮助

cnt = 0;
parfor i=1:n
    cnt = cnt + 1; % legal
    disp(cnt); % illegal
    disp(i); % legal ofc. but out of order
end
也许有人确实有一个聪明的解决方法,但我认为
parfor
迭代的独立性掩盖了进行可靠计数的事实。上述限制,加上使用
evalin
等的限制,都支持这一结论

正如@Jonas所建议的,您可以通过在MATLAB之外发生的副作用获得迭代计数,例如,在某个目录中创建空文件并计数。当然,您可以在MATLAB中执行此操作:

fid = fopen(['countingDir/f' num2str(i)],'w');
fclose(fid);
length(dir('countingDir'));

如果您只想知道大约还剩多少时间,可以运行程序一次,记录最大时间,然后执行此操作

tStart = tic;
parfor i=1:n
  tElapsed = toc(tStart;)
  disp(['Time left in min ~ ', num2str( ( tMax - tElapsed ) / 60 ) ]);
  ...
end
请尝试此FEX文件:


您可以轻松地修改它以返回迭代编号,而不是显示进度条。

类似于进度条的操作也可以这样做

parfor
循环之前:

fprintf('Progress:\n');
fprintf(['\n' repmat('.',1,m) '\n\n']);
在循环过程中:

fprintf('\b|\n');

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

我创建了一个实用程序来执行此操作:


使用Matlab 2017a或更高版本,您可以使用或来实现这一点。以下是如何从第一个链接创建进度条的MathWorks文档示例:

function a = parforWaitbar

D = parallel.pool.DataQueue;
h = waitbar(0, 'Please wait ...');
afterEach(D, @nUpdateWaitbar);

N = 200;
p = 1;

parfor i = 1:N
    a(i) = max(abs(eig(rand(400))));
    send(D, i);
end

    function nUpdateWaitbar(~)
        waitbar(p/N, h);
        p = p + 1;
    end
end
最终结果:


您可以创建N个名为“iter_1”、“iter_2”等的空文本文件,并在每个parfor迭代结束时删除相应的文件。然后你所需要做的就是计算目录中的文件数。@Jonas,这太恶心了。它也会起作用!谢谢我很惊讶MATLAB还没有添加一些东西来简化这个过程。