现在,我已经在matlab, fortran中遇到过几次这个术语…其他的…但我从来没有找到一个解释,它是什么意思,它是什么?所以我在这里问,什么是向量化,例如,“一个循环是向量化的”是什么意思?
当前回答
它指的是在一个步骤中对一个数字列表(或“向量”)进行单一数学运算的能力。你经常在Fortran中看到它,因为它与科学计算有关,而科学计算又与超级计算有关,向量化算术就是在那里首次出现的。如今,几乎所有的桌面cpu都提供某种形式的向量化算法,比如通过英特尔的SSE等技术。gpu还提供了一种向量化算法。
其他回答
它指的是在一个步骤中对一个数字列表(或“向量”)进行单一数学运算的能力。你经常在Fortran中看到它,因为它与科学计算有关,而科学计算又与超级计算有关,向量化算术就是在那里首次出现的。如今,几乎所有的桌面cpu都提供某种形式的向量化算法,比如通过英特尔的SSE等技术。gpu还提供了一种向量化算法。
许多cpu都有“矢量”或“SIMD”指令集,可以同时对两个、四个或更多的数据应用相同的操作。现代x86芯片有SSE指令,许多PPC芯片有“Altivec”指令,甚至一些ARM芯片有一个矢量指令集,称为NEON。
“矢量化”(简化)是重写循环的过程,这样它就不是处理数组中的单个元素N次,而是同时处理数组中的4个元素N/4次。
我选择4是因为它是现代硬件最可能直接支持的32位浮点数或整型数。
向量化与循环展开的区别: 考虑以下非常简单的循环,它添加两个数组的元素并将结果存储到第三个数组中。
for (int i=0; i<16; ++i)
C[i] = A[i] + B[i];
展开这个循环会把它转换成这样:
for (int i=0; i<16; i+=4) {
C[i] = A[i] + B[i];
C[i+1] = A[i+1] + B[i+1];
C[i+2] = A[i+2] + B[i+2];
C[i+3] = A[i+3] + B[i+3];
}
另一方面,向量化它,会产生这样的东西:
for (int i=0; i<16; i+=4)
addFourThingsAtOnceAndStoreResult(&C[i], &A[i], &B[i]);
其中“addFourThingsAtOnceAndStoreResult”是一个占位符,用于任何内在(s)你的编译器用来指定向量指令。
术语:
请注意,大多数现代提前编译器都能够像这样自动向量化非常简单的循环,这通常可以通过compile选项启用(在现代C和c++编译器中,默认情况下是完全优化的,如gcc -O3 -march=native)。openmp# pragma omp simd有时有助于提示编译器,特别是对于“约简”循环,例如对FP数组求和,其中向量化需要假装FP数学是关联的。
更复杂的算法仍然需要程序员的帮助来生成良好的矢量代码;我们称之为手动矢量化,通常使用像x86 _mm_add_ps这样的intrinsic来映射到单个机器指令,例如在Intel cpu上的SIMD前缀和或如何使用SIMD计算字符出现次数。或者甚至使用SIMD短的非循环问题,如最疯狂的最快方式将9字符数字转换为int或无符号int或如何将二进制整数转换为十六进制字符串?
The term "vectorization" is also used to describe a higher level software transformation where you might just abstract away the loop altogether and just describe operating on arrays instead of the elements that comprise them. e.g. writing C = A + B in some language that allows that when those are arrays or matrices, unlike C or C++. In lower-level languages like that, you could describe calling BLAS or Eigen library functions instead of manually writing loops as a vectorized programming style. Some other answers on this question focus on that meaning of vectorization, and higher-level languages.
请看上面的两个答案。我只是想补充一下,想要做向量化的原因是,这些操作可以很容易地由超级计算机和多处理器并行执行,从而产生巨大的性能增益。在单处理器计算机上不会有性能提升。
向量化是将标量程序转换为矢量程序的术语。向量化程序可以从一条指令运行多个操作,而标量程序一次只能对操作数对进行操作。
从维基百科:
标量的方法:
for (i = 0; i < 1024; i++)
{
C[i] = A[i]*B[i];
}
矢量化方法:
for (i = 0; i < 1024; i+=4)
{
C[i:i+3] = A[i:i+3]*B[i:i+3];
}
由英特尔人我想是很容易把握的。
Vectorization is the process of converting an algorithm from operating on a single value at a time to operating on a set of values at one time. Modern CPUs provide direct support for vector operations where a single instruction is applied to multiple data (SIMD). For example, a CPU with a 512 bit register could hold 16 32- bit single precision doubles and do a single calculation. 16 times faster than executing a single instruction at a time. Combine this with threading and multi-core CPUs leads to orders of magnitude performance gains.
链接https://software.intel.com/en-us/articles/vectorization-a-key-tool-to-improve-performance-on-modern-cpus
在Java中,有一个选项可以包含在2020年的JDK 15或2021年的JDK 16中。请参阅此正式版本。