倍频并行功能使单机运行时间变差

问题描述 投票:0回答:2

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

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 设置中设置一些东西,或者在哪些情况下并行化真的很有帮助?

performance parallel-processing octave
2个回答
4
投票

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


有两个主要问题。其中之一是 Ander 在他的评论中提到的,启动并行池需要一两秒。您可以提前打开它(在 MATLAB 中,您可以通过

parpool
来完成此操作)以加快速度。或者,运行单个并行操作,从而打开池,然后重做计时。

第二个问题是操作的简单性。仅仅对一个数字进行平方不会比串行计算快得多。对于如此简单的操作,在工作人员之间来回传递数据是没有意义的。使用更昂贵的函数重做测试,例如

eig()
正如 MATLAB 在其示例中所做的那样。

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

为了更深入的解释,我可以推荐我的这个答案以及其中的参考文献。

作为旁注,我很惊讶你的序列

for
这么快,因为你没有初始化你的输出向量。 预分配非常重要,因为在循环中“增长”数组需要创建一个新数组并将所有先前的内容复制到其中每次迭代
您可能还想考虑不使用
i
j
作为变量名称,因为它们表示虚数单位。它不会对运行时产生太大影响,但可能会导致很难调试的错误。只需使用
idx
ii
或更具描述性的变量名称即可。


0
投票

请注意,如上所示的 for 循环还有另一个问题:它将为动态增长的数组分配内存。您可以通过提前为输出数组分配内存来节省一些时间,例如

向量_y = 零(大小(向量_x));

循环之前。但该任务最简单、最快的解决方案是

向量_y =向量_x .^ 2; %。表示元素明智操作

与循环相比快 1000 倍!

© www.soinside.com 2019 - 2024. All rights reserved.