我了解在 MATLAB 等语言中使用向量化如何通过消除维护循环变量的开销来加速代码,但是向量化实际上是如何在汇编/机器代码中发生的?我的意思是在某个地方仍然必须有一个循环,对吧?
2 回答
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。这甚至更具误导性,因为这些函数可能比本机 matlab loops 慢得多。正如 robince 所说,如今并非所有循环在 matlab 中都很慢,尽管您确实需要知道它们何时工作,何时不工作。
无论如何,你总是需要一个循环,它只是在 matlab 内置函数/BLAS 中实现,而不是用户的 matlab 代码。
是的,还有一个循环。但它能够直接在编译后的代码中循环。Fortran(Matlab 最初基于)C 或 C++ 中的循环本身并不慢。它们在 Matlab 中很慢是动态运行时的一个属性(它们在 Python 等其他动态语言中也较慢)。
由于 Matlab 引入了 Just-In-Time 编译器,循环性能实际上已显着提高 - 因此,避免循环的旧指南在最近的版本中不像以前那么重要。