Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab parfeval';与串行实现相比,它的时间开销是多少?_Matlab_Parallel Processing_Parfor_Spmd - Fatal编程技术网

Matlab parfeval';与串行实现相比,它的时间开销是多少?

Matlab parfeval';与串行实现相比,它的时间开销是多少?,matlab,parallel-processing,parfor,spmd,Matlab,Parallel Processing,Parfor,Spmd,我正在尝试将高斯-赛德尔算法中使用的一些代码并行化,以近似线性方程组的解 简而言之,对于一个NxN矩阵,在一次迭代中,我一个接一个地执行sqrt(N)并行计算会话。在并行计算的一个会话中,我将从向量计算sqrt(N)值的任务分配给可用的工作者 并行计算会话中涉及的代码如下: future_results(1:num_workers) = parallel.FevalFuture; for i = 1:num_workers start_itv = buck_bound+1 + (i -

我正在尝试将高斯-赛德尔算法中使用的一些代码并行化,以近似线性方程组的解

简而言之,对于一个
NxN
矩阵,在一次迭代中,我一个接一个地执行
sqrt(N)
并行计算会话。在并行计算的一个会话中,我将从向量计算
sqrt(N)
值的任务分配给可用的工作者

并行计算会话中涉及的代码如下:

future_results(1:num_workers) = parallel.FevalFuture;
for i = 1:num_workers
    start_itv = buck_bound+1 + (i - 1) * worker_length;
    end_itv = min(buck_bound+1 + i * worker_length - 1, ends_of_buckets(current_bucket));                 
    future_results(i) = parfeval(p, @hybrid_parallel_function, 3, A, b, x, x_last, buck_bound, n, start_itv, end_itv);
end
            
for i = 1:num_workers
    [~, arr, start_itv, end_itv] = fetchNext(future_results(i));               
    x(start_itv:end_itv) = arr;
end
parfeval
调用的函数如下:

function [x_par, start_itv, end_itv] = hybrid_parallel_function (A, b, x, x_last, buck_bound, n, start_itv, end_itv)
    x_par = zeros(end_itv - start_itv + 1, 1);
    for i = start_itv:end_itv
        x_par(i-start_itv+1) = b(i);
        x_par(i-start_itv+1) = x_par(i-start_itv+1) - A(i, 1:buck_bound) * x(1:buck_bound);
        x_par(i-start_itv+1) = x_par(i-start_itv+1) - A(i, buck_bound+1:i-1) * x_last(buck_bound+1:i-1);
        x_par(i-start_itv+1) = x_par(i-start_itv+1) - A(i, i+1:n) * x_last(i+1:n);
        x_par(i-start_itv+1) = x_par(i-start_itv+1) / A(i, i);
    end
end
整个代码可在此处找到:

用于
1000x1000
矩阵的matlab分析器。根据选择的系数矩阵,并行代码比串行代码慢20到135倍(仍然比spmd快得多)

parfeval计算可能会在第50行和第57行之间延迟分割?不过,我无法向自己解释为什么会有这么大的开销。这似乎与调用parfeval的次数有关:我确实通过降低parfeval调用来降低执行时间

有什么可以进一步优化的吗?在C++中,我必须求助于编写代码吗?
请帮忙。多谢各位

这里有一些可能性。最重要的是一个简单的事实,如果您使用的是
'local'
集群类型,那么worker将在单线程代码中运行。在“串行”代码实际上利用了MATLAB固有的多线程的情况下,您已经充分利用了可用的CPU硬件,而使用并行工作程序无法获得任何好处。我们不确定你的情况是否如此,但我强烈怀疑这是因为代码

并行运行有一些开销,正如您所观察到的,运行更少的
parfeval
调用可以降低这些开销。您编写的代码将整个
A
矩阵复制到每个工作人员多次。您不需要更改
A
,因此可以使用
parallel.pool.Constant
来避免重复复制

虽然
parfeval
更灵活,但在可以应用
parfor
的情况下,它的效率往往低于
parfor

是的,您可以期望工作人员在第一次
parfeval
调用完成后立即开始工作


(很抱歉,这不是一个正确的“答案”,因此可能会有一些善良的灵魂出现,并很快将其删除,但有太多的内容无法放入评论中)。

这里有一些可能性。最重要的是一个简单的事实,如果您使用的是
'local'
集群类型,那么worker将在单线程代码中运行。在“串行”代码实际上利用了MATLAB固有的多线程的情况下,您已经充分利用了可用的CPU硬件,而使用并行工作程序无法获得任何好处。我们不确定你的情况是否如此,但我强烈怀疑这是因为代码

并行运行有一些开销,正如您所观察到的,运行更少的
parfeval
调用可以降低这些开销。您编写的代码将整个
A
矩阵复制到每个工作人员多次。您不需要更改
A
,因此可以使用
parallel.pool.Constant
来避免重复复制

虽然
parfeval
更灵活,但在可以应用
parfor
的情况下,它的效率往往低于
parfor

是的,您可以期望工作人员在第一次
parfeval
调用完成后立即开始工作


(很抱歉,这不是一个正确的“答案”,因此可能会有一些善良的灵魂出现并很快将其删除,但有太多的内容无法放入注释中)。

您是如何配置并行池的?默认情况下,MATLAB使用多个MATLAB会话,并在它们之间通信数据。这是为在计算集群上运行而设计的,集群中的每个节点运行一个会话。不过,您可以将其配置为使用基于线程的并行性。在任何情况下,大型作业的并行性都比许多小型作业好。您可能是对的,我将在更新到R2020后立即尝试parpool(“线程”),谢谢。您是如何配置并行池的?默认情况下,MATLAB使用多个MATLAB会话,并在它们之间通信数据。这是为在计算集群上运行而设计的,集群中的每个节点运行一个会话。不过,您可以将其配置为使用基于线程的并行性。在任何情况下,大型作业的并行性都比许多小型作业好。您可能是对的,我将在更新到R2020后立即尝试parpool(“线程”),谢谢。嗨,谢谢您的回答!希望我确实正确地写下了parallel.pool.Constant()。不幸的是,时间一点也没有改善。正如您和Cris Luengo所说,我可能必须尝试parpool(“线程”),它只能从R2020a开始使用,因此我必须等待一段时间才能更新。同时,我也研究了STD::To线,我认为我可能有一个很好的机会在C++中编写它,即使它意味着对矩阵乘法部分进行编译。@催化剂:如果你要做C++实现,不要使用<代码> STD::线程< /代码>,使用任何高级抽象。我更喜欢OpenMP,但您也可以看看Intel踏板块或任何数量的库,它们简化了并行化算法的问题。在OpenMP中,只需将
#pragma parallel for
放在for循环前面即可。您好,感谢您的回答!希望我确实正确地写下了parallel.pool.Constant()。不幸的是,时间一点也没有改善。正如您和Cris Luengo所说,我可能必须尝试parpool(“线程”),这是唯一可用的开始