【发布时间】:2017-06-02 02:22:29
【问题描述】:
我有一个运行时间相当长的 parfor 循环(比如说 100,000 次迭代,每次迭代大约需要一分钟),我正在运行 36 个内核。我注意到在工作接近尾声时,大量内核处于空闲状态,而少数内核完成了我认为每个工作人员必须进行多次迭代的工作。这会导致浪费大量计算时间来等待一名工作人员完成几项工作,而其他工作人员则处于空闲状态。
以下脚本显示了该问题(使用文件交换实用程序Par.m):
% Set up parallel pool
nLoop = 480;
p1 = gcp;
% Run a loop
pclock = Par(nLoop);
parfor iLoop = 1:nLoop
Par.tic;
pause(0.1);
pclock(iLoop) = Par.toc;
end
stop(pclock);
plot(pclock);
% Process the timing info:
runs = [[pclock.Worker]' [pclock.ItStart]' [pclock.ItStop]'];
nRuns = arrayfun(@(x) sum(runs(:,1) == x), 1:max(runs));
starts = nan(max(nRuns), p1.NumWorkers);
ends = nan(max(nRuns), p1.NumWorkers);
for iS = 1:p1.NumWorkers
starts(1:nRuns(iS), iS) = sort(runs(runs(:, 1) == iS, 2));
ends(1:nRuns(iS), iS) = sort(runs(runs(:, 1) == iS, 3));
end
firstWorkerStops = min(max(ends));
badRuns = starts > firstWorkerStops;
nBadRuns = sum(sum(badRuns)) - (p1.NumWorkers-1);
fprintf('At least %d (%3.1f%%) iterations run inefficiently.\n', ...
nBadRuns, nBadRuns/nLoop * 100);
在我看来,每个工作人员都应该一直忙到队列为空,之后所有工作人员都处于空闲状态。但在这里看起来这并没有发生 - 在 480 次迭代中,在另一个工作人员闲置了一个完整的周期之后,我在工作人员上开始了 6 到 20 次迭代。这个数字似乎与循环迭代次数呈线性关系,接近总数的 2%。通过有限的测试,这似乎在 Matlab 2016b 和 2014b 中是一致的。
是否有任何理由认为这是预期的行为,或者这只是 parfor 实现中编写不佳的调度程序?如果是这样,我该如何构建它,这样我就不会和闲置的工人坐在一起这么久?
【问题讨论】:
标签: matlab parallel-processing parfor