【发布时间】:2015-06-24 16:54:35
【问题描述】:
我正在编写 matlab 代码来执行 3 维积分:
function [ fint ] = int3d_ser(R0, Rf, N)
Nr = N;
Nt = round(pi*N);
Np = round(2*pi*N);
rs = linspace(R0, Rf, Nr);
ts = linspace(0, pi, Nt);
ps = linspace(0, 2*pi, Np);
dr = rs(2)-rs(1);
dt = ts(2)-ts(1);
dp = ps(2)-ps(1);
C = 1/((4/3)*pi);
fint = 0.0;
for ir = 2:Nr
r = rs(ir);
r2dr = r*r*dr;
for it = 1:Nt-1
t = ts(it);
sintdt = sin(t)*dt;
for ip = 1:Np-1
p = ps(ip);
fint = fint + C*r2dr*sintdt*dp;
end
end
end
end
对于关联的int3d_par (parfor) 版本,我打开了一个 matlab 池并将for 替换为parfor。我在更多内核上运行它得到了相当不错的加速(我的测试是从 2 到 8 个内核)。
但是,当我在批处理模式下运行相同的集成时:
function [fint] = int3d_batch_cluster(R0, Rf, N, cluster, ncores)
%%% note: This will not give back the same value as the serial or parpool version.
%%% If this was a legit integration, I would worry more about even dispersion
%%% of integration nodes per core, but I just want to benchmark right now so ... meh
Nr = N;
Nt = round(pi*N);
Np = round(2*pi*N);
rs = linspace(R0, Rf, Nr);
ts = linspace(0, pi, Nt);
ps = linspace(0, 2*pi, Np);
dr = rs(2)-rs(1);
dt = ts(2)-ts(1);
dp = ps(2)-ps(1);
C = 1/((4/3)*pi);
rns = floor( Nr/ncores )*ones(ncores,1);
RNS = zeros(ncores,1);
for icore = 1:ncores
if(sum(rns) ~= Nr)
rns(icore) = rns(icore)+1;
end
end
RNS(1) = rns(1);
for icore = 2:ncores
RNS(icore) = RNS(icore-1)+rns(icore);
end
rfs = rs(RNS);
r0s = zeros(ncores,1);
r0s(2:end) = rfs(1:end-1);
j = createJob(cluster);
for icore = 1:ncores
r0 = r0s(icore);
rf = rfs(icore);
rn = rns(icore);
trs = linspace(r0, rf, rn);
t{icore} = createTask(j, @int3d_ser, 1, {r0, rf, rn});
end
submit(j);
wait(j);
fints = fetchOutputs(j);
fint = 0.0;
for ifint = 1:length(fints)
fint = fint + fints{ifint};
end
end
我注意到它要快得多。为什么以批处理模式执行此集成与在 parfor 中执行此集成不同?
作为参考,我使用 N 测试代码,从 10 和 20 之类的小数字(以在运行时的多项式近似中获得常数)到 1000 和 2000 之类的更大数字。由于我分配了theta 和 phi 方向上的集成节点数为给定 N 的常数倍数。
对于 2000 个节点,parfor 版本大约需要 630 秒,而在批处理模式下相同数量的节点大约需要 19 秒(其中大约 12 秒只是我们对于 10 个集成节点也得到的开销通信)。
【问题讨论】:
-
您要将哪个
for替换为parfor?它可能会对嵌套循环结构产生影响(例如,点击parfor并多次产生并行设置/拆卸开销,或者执行不太理想的切片结构)。批处理版本代码在进行并行调用时似乎已经“扁平化”了嵌套循环结构(即通过预先计算输入块并在每个块内执行嵌套循环),这可能会降低并行性开销。跨度> -
另一件事是,如果我了解您将
parfor放在哪里,批处理版本移动的数据要少得多:它只是传递了r0、rf、和rn参数和中间变量在每个worker 上本地构建,但是int3d_ser内部的parfor会导致在master 上创建的临时变量的子集被编组并发送给每个worker。跨度> -
例如如果您使用
int3d_batch_cluster函数并将createTask调用替换为parfor icore = 1:ncores围绕对int3d_ser的正常函数调用,会发生什么?这将告诉您它是parfor机制本身,还是您的代码如何隐式构建要发送给工作人员的工作批次。 -
我有非常外部的 for 循环来执行 parfor,以便为 parfor 提供更多内容,这样开销是值得的。
-
您能检查一下您的批处理集群代码吗?其中有几个未使用的变量。
标签: performance matlab runtime parfor