我已经阅读过这篇文章,但我仍然不明白为什么向量化的代码更快。
在for循环中,我可以使用parfor进行并行计算。如果向量化的代码更快,是否意味着它自动并行化了?
我已经阅读过这篇文章,但我仍然不明白为什么向量化的代码更快。
在for循环中,我可以使用parfor进行并行计算。如果向量化的代码更快,是否意味着它自动并行化了?
不行。您混淆了两个重要的概念:
例如,请考虑以下微不足道的情况:
s=0;
for i=1:length(v),
s = s+v(i);
end
和
sum(v)
为了证明这两个函数的运行时间差异,您应该使用tic
和toc
。有大约10个类似的常用于向量操作的函数,例如:bsxfun
、repmat
、length
、find
。向量化是有效使用MATLAB的标准部分。在您能够有效地向量化代码之前,您只是MATLAB世界中的游客,而不是公民。
parfor
。 parfor
不是万能药,它是一种可以被使用和误用的工具(请尝试对上面的求和例子使用parfor
)。不是所有的循环都可以并行化。 parfor
是设计用于任务并行类型的问题,其中循环的每次迭代互相独立。这是使用parfor -loop
的一个关键要求。虽然在许多情况下,parfor
可以帮助很多,但可以进行大幅度优化的循环类型很少出现。
我同意carlosdc的回答。 然而,需要记住的是Matlab自6.5版本以来包含了一个JIT编译器,可以加速for循环等操作。
我对你的sum示例进行了快速测试,其中v
有一百万个元素,测试结果如下:
sum(v)
:4.3毫秒for循环版本
:16毫秒for循环版本,未开启JIT
:966毫秒可以通过以下方式打开或关闭JIT:
feature accel off
feature accel on
当然,通过向量化代码来提高四倍的性能仍然是值得的,但是对于那些本来就适合使用for循环的问题,我们不应该像过去一样害怕使用它们。通常情况下,良好向量化的代码往往可以同时更简单、更少出错、更快。
在现代计算机中,寄存器(临时存储器,用于数学计算等)具有许多位并可以同时操作多个数字。例如,如果您的数据是uint8(8位),则可以在一个CPU时钟中为每个数字添加一个数字,或者将它们全部放在寄存器中,并在一个CPU时钟中为所有数字加上一个数字。这样,您的工作速度比使用for循环快8倍。
这在某种意义上是并行化的,但不像parfor。Parfor使用计算机CPU的多个核心,而以上方法则更有效地使用一个核心。如果两者都使用,则可以实现更高的速度。