Performance 为什么批处理模式比parfor快得多?

Performance 为什么批处理模式比parfor快得多?,performance,matlab,runtime,parfor,Performance,Matlab,Runtime,Parfor,我正在编写matlab代码来执行三维积分: 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 =

我正在编写matlab代码来执行三维积分:

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\u 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个集成节点也是如此)。

Mathworks
支持人员交谈后,看来我对parfor的工作原理有一个基本的误解。我的印象是,
parfor
在共享内存与分布式内存方面的表现类似于
openMP
,而批处理模式则类似于
mpi

事实证明,
parfor
实际上也使用分布式内存。比如说,当我创建4个批处理函数时,创建新流程的开销会发生4次。我认为使用
parfor
会导致开销只发生1次,然后
parfor
会发生在相同的内存空间中。事实并非如此


在我的示例代码中,事实证明,对于
parfor
的每次迭代,我实际上会产生创建新线程的开销。当比较“苹果对苹果”时,我应该创建与我在
parfor
循环中的迭代次数相同的批处理调用。这就是为什么
parfor
函数花费的时间要长得多的原因-我的多处理开销要大得多。

您要用
parfor
替换哪个
for
?这可能会对嵌套循环结构产生影响(例如,多次点击
parfor
并导致并行设置/拆卸开销,或者执行不太理想的切片结构)。批处理版本代码在到达并行调用时似乎已经“扁平化”了嵌套循环结构(即,通过预先计算输入块并在每个块中执行嵌套循环),这可以降低并行开销。另一件事是,如果我理解您将
parfor
放在哪里,批处理版本移动的数据要少得多:它只是传递
r0
rf
rn
参数,中间变量在每个worker上本地构建,但是,
int3d\u ser
内部的
parfor
会导致在主机上创建的临时变量子集被编组并发送给每个工作者。如果使用
int3d\u batch\u cluster
函数并围绕对
int3d\u ser
的正常函数调用使用
parfor icore=1:ncores
替换
createTask
调用,会发生什么情况?这将告诉您这是
parfor
机制本身,还是您的代码隐式地构造了要发送给工作人员的工作批。我有一个非常外部的for循环来执行parfor,以便为parfor提供更多的内容,这样做的开销是值得的。您能检查一下批处理集群代码吗?其中有几个未使用的变量。这是否意味着批处理模式比parfor更快?