现在,我已经在matlab, fortran中遇到过几次这个术语…其他的…但我从来没有找到一个解释,它是什么意思,它是什么?所以我在这里问,什么是向量化,例如,“一个循环是向量化的”是什么意思?
当前回答
向量化在科学计算中被广泛使用,在科学计算中需要有效地处理大量数据。
在真正的编程应用中,我知道它在NUMPY中使用(不确定其他)。
Numpy (python中用于科学计算的包)使用向量化来快速操作n维数组,如果使用内置的python选项来处理数组,通常会较慢。
尽管有大量的解释,以下是NUMPY文档页中矢量化的定义
向量化描述了代码中没有任何显式的循环、索引等——当然,这些事情只是在优化的、预编译的C代码的“幕后”发生。向量化代码有很多优点,其中包括:
向量化的代码更简洁,更易于阅读 更少的代码行通常意味着更少的错误 代码更接近于标准的数学符号 (这使得正确编写数学代码更容易 构造) 向量化会产生更多的“python式”代码。没有 向量化,我们的代码就会充斥着低效的和 难以读取循环。
其他回答
许多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.
由英特尔人我想是很容易把握的。
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中。请参阅此正式版本。
向量化在科学计算中被广泛使用,在科学计算中需要有效地处理大量数据。
在真正的编程应用中,我知道它在NUMPY中使用(不确定其他)。
Numpy (python中用于科学计算的包)使用向量化来快速操作n维数组,如果使用内置的python选项来处理数组,通常会较慢。
尽管有大量的解释,以下是NUMPY文档页中矢量化的定义
向量化描述了代码中没有任何显式的循环、索引等——当然,这些事情只是在优化的、预编译的C代码的“幕后”发生。向量化代码有很多优点,其中包括:
向量化的代码更简洁,更易于阅读 更少的代码行通常意味着更少的错误 代码更接近于标准的数学符号 (这使得正确编写数学代码更容易 构造) 向量化会产生更多的“python式”代码。没有 向量化,我们的代码就会充斥着低效的和 难以读取循环。
简而言之,矢量化意味着优化算法,使其能够利用处理器中的SIMD指令。
AVX, AVX2 and AVX512 are the instruction sets (intel) that perform same operation on multiple data in one instruction. for eg. AVX512 means you can operate on 16 integer values(4 bytes) at a time. What that means is that if you have vector of 16 integers and you want to double that value in each integers and then add 10 to it. You can either load values on to general register [a,b,c] 16 times and perform same operation or you can perform same operation by loading all 16 values on to SIMD registers [xmm,ymm] and perform the operation once. This lets speed up the computation of vector data.
在向量化中,我们利用了这一点,通过重构数据,我们可以对其执行SIMD操作,并加快程序的速度。
矢量化的唯一问题是处理条件。因为条件分支了执行流。这可以通过屏蔽来处理。通过将条件建模成算术运算。如。如果我们想在value上加10如果它大于100。我们也可以。
if(x[i] > 100) x[i] += 10; // this will branch execution flow.
或者我们可以将条件建模为算术运算,创建一个条件向量c,
c[i] = x[i] > 100; // storing the condition on masking vector
x[i] = x[i] + (c[i] & 10) // using mask
这是一个非常琐碎的例子…因此,c是我们的掩蔽向量,我们使用它来执行基于其值的二进制操作。这避免了执行流的分支,并支持向量化。
向量化和并行化同样重要。因此,我们应该尽可能多地利用它。所有现代处理器都有SIMD指令来处理繁重的计算工作负载。我们可以使用向量化来优化我们的代码以使用这些SIMD指令,这类似于并行化我们的代码以在现代处理器上可用的多个核上运行。
最后我想提一下OpenMP,它允许你使用pragmas向量化代码。我认为这是一个很好的起点。OpenACC也是如此。
它指的是在一个步骤中对一个数字列表(或“向量”)进行单一数学运算的能力。你经常在Fortran中看到它,因为它与科学计算有关,而科学计算又与超级计算有关,向量化算术就是在那里首次出现的。如今,几乎所有的桌面cpu都提供某种形式的向量化算法,比如通过英特尔的SSE等技术。gpu还提供了一种向量化算法。