分段多项式评价的并行化

时间:2017-02-28 00:51:07

标签: multithreading matlab parallel-processing vectorization spline

我正在尝试评估一个大的分段多项式中的点,这是从三次样条求得的。这需要很长时间才能完成,我想加快速度。

因此,我想用并行过程来评估分段多项式的点,而不是顺序。

代码:

z = zeros(1e6, 1) ;    % preallocate some memory for speed
Y = rand(11220,161) ;  %some data, rand for generating a working example
X = 0 : 0.0125 : 2 ;   % vector of data sites
pp = spline(X, Y) ;    % get the piecewise polynomial form of the cubic spline. 

结果结构很大。

for t = 1 : 1e6  % big number
    hcurrent = ppval(pp,t); %evaluate the piecewise polynomial at t
    z(t) = sum(x(t:t+M-1).*hcurrent,1) ; % do some operation of the interpolated value. Most likely not relevant to this question.
end

不幸的是,使用矩阵形式并使用:

hcurrent = flipud(ppval(pp, 1: 1e6 ))

需要太多内存才能处理,因此无法完成。有没有办法可以批处理这段代码来加快速度呢?

3 个答案:

答案 0 :(得分:0)

使用parfor命令进行并行循环。请参阅here,同时将z向量预先计算为z(j) = x(j:j+M-1),并将parfor中的hcurrent计算为加速。

答案 1 :(得分:0)

样条参数估计可以用矩阵形式编写。

一旦用Matrix形式编写并解决它,您可以使用模型矩阵使用矩阵乘法来评估所有数据点上的样条曲线,这可能是MATLAB中调整最多的操作。

答案 2 :(得分:0)

对于标量第二个参数,如在您的示例中,您正在处理两个问题。首先,存在大量的函数调用开销和冗余计算(例如,每次循环迭代都调用unmkpp(pp))。其次,ppval被认为是通用的,所以它没有完全矢量化,并且做了许多在你的情况下不必要的事情。

下面是利用问题结构的矢量化代码(例如,t是一个大于0的整数),避免函数调用开销,将一些计算移到主{{1循环(以一点额外的内存为代价),摆脱for内的for循环:

ppval

结果代码占用n = 1e6; z = zeros(n,1); X = 0:0.0125:2; Y = rand(11220,numel(X)); pp = spline(X,Y); [b,c,l,k,dd] = unmkpp(pp); T = 1:n; idx = discretize(T,[-Inf b(2:l) Inf]); % Or: [~,idx] = histc(T,[-Inf b(2:l) Inf]); x = bsxfun(@power,T-b(idx),(k-1:-1:0).').'; idx = dd*idx; d = 1-dd:0; for t = T hcurrent = sum(bsxfun(@times,c(idx(t)+d,:),x(t,:)),2); z(t) = ...; end 示例的大约34%的时间。请注意,由于矢量化,计算以不同的顺序执行。由于浮点数学的性质,这将导致n=1e6的输出与我的优化版本之间的细微差别。任何差异都应该是ppval的几次。你仍然可以尝试使用eps(hcurrent)来进一步加快计算速度(有四个已经在运行的工作人员,我的系统只占你代码原始时间的12%)。

我认为以上是概念证明。如果您的示例与您的实际代码和数据不符,我可能会过度优化上面的代码。在这种情况下,我建议您创建自己的优化版本。您可以在命令窗口中键入parfor来查看ppval的代码。您可以通过查看问题的结构以及edit ppval向量中最终需要的内容来实现进一步的优化。

在内部,z仍然使用已被弃用的histc。我上面的代码使用discretize执行相同的任务as suggested by the documentation