【发布时间】:2021-10-10 15:35:14
【问题描述】:
在开发 parfor 循环时,通常最好从串行循环开始以使用小数据集进行测试,然后添加“par”以扩展到大样本集等。串行运行时,获得有关的诊断信息非常好然而,当使用 parfor 循环处理大量数据集诊断信息时,for 循环的每次迭代都应关闭。
所以问题是:有没有办法以编程方式检测是否在 for 循环和 parfor 循环中执行?这种方式可以像if ~isParfor; fprintf(...); end
【问题讨论】:
在开发 parfor 循环时,通常最好从串行循环开始以使用小数据集进行测试,然后添加“par”以扩展到大样本集等。串行运行时,获得有关的诊断信息非常好然而,当使用 parfor 循环处理大量数据集诊断信息时,for 循环的每次迭代都应关闭。
所以问题是:有没有办法以编程方式检测是否在 for 循环和 parfor 循环中执行?这种方式可以像if ~isParfor; fprintf(...); end
【问题讨论】:
您可以使用未记录的命令feature('isdmlworker') 来确定代码是否正在工作器上运行。如果在工作人员上运行,则返回true,否则返回false。请注意,虽然这个命令已经存在了很长时间并且看起来很稳定,但理论上它是无证的并且可能会发生变化。
或者,您可以使用记录在案的 usejava('desktop'),如果您使用 MATLAB 桌面运行,则返回 true,否则返回 false(这是工作人员的情况)。这是对工作人员的一个很好的近似,只要您有时不在没有桌面的情况下运行 MATLAB 本身(即使用 -nodesktop 选项启动它)。
还请注意,如果您不启动工作池,parfor 在本地运行就像 for 循环一样,所以这两个都将返回 false - 我想这可能是你的想要,但无论如何都值得注意。
【讨论】:
是的,你可以!使用getCurrentTask 可以告诉您正在执行的操作是否在工作人员上完成。检查此代码以获得简单的演示:
clc
clear all
A1 = zeros(10,10);
A2 = zeros(10,10);
Check1 = zeros(1,10);
Check2 = zeros(1,10);
parfor ix = 1:10
Check1(ix) = ~isempty(getCurrentTask());
myTemp = zeros(1,10);
for jx = 1:10
myTemp(jx) = ix + jx;
end
A1(ix,:) = myTemp;
end
clear myTemp
for ix = 1:10
Check2(ix) = ~isempty(getCurrentTask());
myTemp = zeros(1,10);
for jx = 1:10
myTemp(jx) = ix + jx;
end
A2(ix,:) = myTemp;
end
Check1
Check2
输出这个:
Check1 =
1 1 1 1 1 1 1 1 1 1
Check2 =
0 0 0 0 0 0 0 0 0 0
因此,可以仅检查“检查”变量的第一个条目(即在任何一种情况下的第一次迭代中)并推断您是否 (1) 或不是 (0) 在 parfor 循环中。
【讨论】:
这非常适合在串行但不并行工作的通用函数中使用,例如绘图和文本到语音。当您的分析函数无法运行时,它会优雅地保持惰性。
function b = isParfor()
%returns 1 if in a parfor loop
b = ~isempty(getCurrentTask());
end
【讨论】: