24

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

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

4

3 回答 3

20

不,你混合了两个重要的概念:

  • MATLAB 旨在非常快速地执行向量运算。MATLAB 是一种解释型语言,这就是为什么它的循环如此缓慢的原因。MATLAB 通过提供极快的(通常用 C 语言编写,并针对特定架构进行了优化)和经过良好测试的函数来对向量进行操作,从而回避了这个问题。这里真的没有什么神奇之处,它只是一堆辛勤的工作和多年不断的小改进。

例如,考虑一个简单的情况,例如:

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

sum(v)

您可能应该使用 tic 和 toc 对这两个函数进行计时,以使自己相信运行时的差异。对向量进行操作的类似常用函数大约有 10 个,例如:bsxfunrepmatlengthfind。矢量化是有效使用 MATLAB 的标准部分。在您可以有效地矢量化代码之前,您只是 MATLAB 世界中的游客,而不是公民。

  • 最新版本的 MATLAB 提供 parfor。parfor 不是灵丹妙药,它是一种可以使用和误用的工具(在上面的 sum 示例中尝试 parfor)。并非所有的 fors 都可以解释。parfor 专为任务并行类型的问题而设计,其中循环的每次迭代都相互独立。这是使用 parfor 循环的关键要求。

虽然在许多情况下 parfor 可以提供很多帮助,但很少发生可以为非常大的收益进行 parfor 的循环类型。

于 2012-12-26T06:27:13.867 回答
16

我同意 carlosdc 的回答。然而,重要的是要记住,自 6.5 版以来,Matlab 已包含一个 JIT 编译器,用于加速 for 循环等。

我用一百万个元素对你的求和示例进行了快速测试,v得到了以下结果:

  • sum(v): 4.3 毫秒
  • for-loop version: 16 毫秒
  • for-loop version, no JIT: 966 毫秒

JIT 可以像这样打开和关闭:

feature accel off
feature accel on

通过矢量化代码来改进 4 因素当然仍然是值得的,但不应该害怕 for 循环,因为它们曾经是一个很好的解决方案。通常,一段良好的矢量化代码通常可以更简单、更不容易出错并且同时更快。

于 2013-01-02T20:53:30.947 回答
2

在现代计算机中,寄存器(用于数学的临时存储器,以及其他用途)有很多位,可以一起处理多个数字。例如,如果您的数据是 uint8(8 位),您可以在一个 CPU 时钟中为每个添加一个数字,或者您可以将其中的 8 个放在寄存器中,然后在一个 CPU 时钟中为所有这些添加一个数字. 这样你的工作速度比 for 循环快 8 倍。

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

于 2012-12-26T09:27:22.600 回答