微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Octave 并行功能恶化了单机上的运行时间

如何解决Octave 并行功能恶化了单机上的运行时间

我尝试通过octave创建一个测试代码来评估我的带有8核处理器的Windows机器上的时间效率(单机并行);从提供的简单代码示例 in the documentation 开始,如下所示:

pkg load parallel
fun = @(x) x^2;
vector_x = 1:20000;

# Serial Format of the Program
tic()
for i=1:20000
vector_y(1,i)=vector_x(1,i)^2;   
endfor
toc()

# Parallel Format of the Program
tic()
vector_y1 = pararrayfun(nproc,fun,vector_x);
toc()

令我惊讶的是,串行代码所需的时间比使用并行函数要快得多。串行用例运行时间为 0.0758219 秒,并行用例运行时间为 3.79864 秒。

有人能解释一下是并行开销还是我应该在我的 Octave 设置中设置一些东西,或者在哪些情况下并行化真的有帮助?

解决方法

TL;DR:在计时器之外打开你的池并选择一个更困难的操作。


有两个主要问题。一个是 Ander 在 his comment 中提到的,启动并行池需要一两秒钟。您可以事先打开它(在 MATLAB 中,您可以通过 parpool 执行此操作)以加快速度。或者,运行单个并行操作,从而打开池,然后重新计时。

第二个问题是操作的简单性。只是对一个数字进行平方不能比它已经连续运行的速度快得多。对于如此简单的操作,在工作人员之间来回传递数据是没有意义的。使用更昂贵的功能重做您的测试,例如eig() 就像 MATLAB 在他们的例子中所做的那样。

如果您的操作的运行时间大大超过了将数据传入和传出 worker 的开销,那么并行化就非常有用。基本上这意味着您要么有一个非常大的数据集,您需要对每个项目执行相同的操作(例如,取每 1000 行左右的平均值),要么您有一些繁重但独立的任务要执行。

对于更深入的解释,我可以推荐 this answer of mine 和其中的参考资料。

顺便说一句,鉴于您没有初始化输出向量,我很惊讶您的序列 for 如此之快。 Preallocation 非常重要,因为在循环中“增长”数组需要创建一个新数组并将之前的所有内容复制到每次迭代
您可能还想考虑不使用 ij 作为变量名称 as they denote the imaginary unit。它不会对运行时产生太大影响,但会导致非常难以调试的错误。只需使用 idxii 或更具描述性的变量名称。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。