为什么矢量化代码比MATLAB中的循环运行得更快?

为什么矢量化代码比MATLAB中的循环运行得更快?,matlab,for-loop,parallel-processing,vectorization,Matlab,For Loop,Parallel Processing,Vectorization,我读过,但我仍然不明白为什么矢量化代码更快 在for循环中,我可以使用parfor进行并行计算。如果矢量化代码速度更快,是否意味着它会自动并行化?否。您混合了两个重要概念: MATLAB设计用于快速执行向量运算。MATLAB是一种解释语言,这就是为什么它的循环速度如此之慢。MATLAB通过提供极快的(通常用C编写,并针对特定的体系结构进行了优化)和经过良好测试的函数来对向量进行操作,从而避开了这个问题。这里真的没有什么魔力,只是一堆艰苦的工作和多年不断的小改进 例如,考虑以下一个简单的情况:

我读过,但我仍然不明白为什么矢量化代码更快


在for循环中,我可以使用parfor进行并行计算。如果矢量化代码速度更快,是否意味着它会自动并行化?

否。您混合了两个重要概念:

  • MATLAB设计用于快速执行向量运算。MATLAB是一种解释语言,这就是为什么它的循环速度如此之慢。MATLAB通过提供极快的(通常用C编写,并针对特定的体系结构进行了优化)和经过良好测试的函数来对向量进行操作,从而避开了这个问题。这里真的没有什么魔力,只是一堆艰苦的工作和多年不断的小改进
例如,考虑以下一个简单的情况:

s=0;
for i=1:length(v),
    s = s+v(i);
end

您可能应该使用tic和toc对这两个函数计时,以使自己确信运行时的差异。大约有10个类似的常用函数对向量进行操作,例如:
bsxfun
repmat
length
find
。矢量化是有效使用MATLAB的标准部分。除非你能有效地将代码矢量化,否则你只是MATLAB世界的游客,而不是公民

  • MATLAB的最新版本提供了parfor。parfor不是一个银弹,它是一个可以被使用和误用的工具(在上面的sum示例中尝试parfor)。并不是所有的FOR都能被使用。parfor设计用于任务并行类型的问题,其中循环的每个迭代都独立于其他迭代。这是使用parfor循环的关键要求

虽然在许多情况下,parfor可以帮助很多,但可以用于获得非常大增益的循环类型很少出现。

在现代计算机中,寄存器(用于数学的临时内存,以及其他用途)有许多位,可以一起操作多个数。例如,如果您的数据是uint8(8位),您可以在一个CPU时钟中为每个数据添加一个数字,或者您可以将其中的8个数据放在寄存器中,并在一个CPU时钟中为所有数据添加一个数字。这样,您的工作速度比for loop快8倍


这在某种意义上是并行化,但不像parfor。Parfor使用多个CPU核心,在上述方法中,一个核心的使用效率更高。如果你同时使用它们,你可以获得更高的速度。

我同意carlosdc的答案。 但是,重要的是要记住,Matlab自6.5版以来就包含了一个JIT编译器,用于加速循环等

我用
v
中的一百万个元素快速测试了你的sum示例,得到了以下结果:

  • 总和(v)
    :4.3毫秒
  • 循环版本的
    :16毫秒
  • 对于循环版本,无JIT
    :966毫秒
JIT可以按如下方式打开和关闭:

feature accel off
feature accel on

通过矢量化代码来提高性能的一个因素4当然仍然是值得的,但是for循环不应该像以前那样让人害怕,因为它们在其他方面是一个很好的解决方案。但是,通常情况下,一段矢量化良好的代码通常会更简单,更不容易出错,同时速度更快。

您错过了一件重要的事情——matlab是一种解释性语言。这就是为什么它的循环速度如此之慢。特别是与高度优化的矩阵运算相比,matlab是为其设计的。谢:谢谢@Leonid Beschastny:我编辑了我的答案,以反映为什么matlab中的循环如此缓慢。谢谢。您可能还想补充一点,解释语言中循环速度慢的原因是每个函数调用都会带来一些开销。因此,当使用一百万个元素的数组调用函数一次时,要比使用标量调用它一百万次快得多。forloops在简单问题中仍然更好。同样适用于forloops。parforloops仅在问题需要大量计算时才能正常工作。否则,parforloops将花费太多低效的时间将作业分配给其他内核。此外,Matlab现在内置了一个JIT编译器,极大地缩小了for循环和矢量化代码之间的差距,正如我自己的答案所示。下面给出的答案是正确的,但事实上,我相信大型矩阵运算实际上可以自动并行运行。
feature accel off
feature accel on