【发布时间】:2012-09-18 21:08:04
【问题描述】:
我了解在 MATLAB 等语言中使用向量化如何通过消除维护循环变量的开销来加速代码,但向量化实际上是如何在汇编/机器代码中发生的?我的意思是在某个地方仍然必须有一个循环,对吧?
【问题讨论】:
标签: matlab vectorization
我了解在 MATLAB 等语言中使用向量化如何通过消除维护循环变量的开销来加速代码,但向量化实际上是如何在汇编/机器代码中发生的?我的意思是在某个地方仍然必须有一个循环,对吧?
【问题讨论】:
标签: matlab vectorization
是的,还有一个循环。但它能够直接在编译后的代码中循环。 Fortran(Matlab 最初基于)C 或 C++ 中的循环本身并不慢。它们在 Matlab 中很慢是动态运行时的一个属性(它们在 Python 等其他动态语言中也很慢)。
自从 Matlab 引入了 Just-In-Time 编译器以来,循环性能实际上已显着提高 - 因此,避免循环的旧指南在最近的版本中不如以前那么重要了。
【讨论】:
Matlab 的“向量化”概念与向量指令概念(例如 SSE)完全不同。这是两组人之间的常见误解:matlab 程序员和 C/asm 程序员。 Matlab 的“向量化”这个词是常用的,仅以矩阵索引(向量)的形式表达循环,有时是关于用基本矩阵/向量运算(BLAS ),而不是编写循环本身。 Matlab“矢量化”代码不一定表示为矢量化 CPU 指令。考虑以下代码:
A = rand(1000);
B = (A(1:2:end,:)+A(2:2:end,:))/2;
此代码计算两个相邻矩阵行的平均值。这是一个“矢量化”的 matlab 表达式。但是,由于 matlab 按列存储矩阵(列在内存中是连续的),因此该操作不会轻易更改为对 SSE 向量的操作:由于我们按行执行操作,因此您需要加载到向量中的数据不会连续存储在记忆中。
另一方面,这段代码
A = rand(1000);
B = (A(:,1:2:end)+A(:,2:2:end))/2;
可以利用 SSE 指令和流指令,因为我们一次对两个相邻的列进行操作。
因此,matlab 的“向量化”并不等同于使用 CPU 向量指令。它只是一个用来表示缺少 MATLAB 中实现的循环的词。更令人困惑的是,有时人们甚至使用这个词来表示某些循环已经使用 内置 函数实现,例如 arrayfun 或 bsxfun。这更容易误导,因为这些函数可能是significantly slower than native matlab loops。正如 robince 所说,现在并非所有循环在 matlab 中都很慢,尽管您确实需要知道它们何时工作,何时不工作。
无论如何,你总是需要一个循环,它只是在 matlab 内置函数/BLAS 中实现,而不是用户的 matlab 代码。
【讨论】: