现在,我已经在matlab, fortran中遇到过几次这个术语…其他的…但我从来没有找到一个解释,它是什么意思,它是什么?所以我在这里问,什么是向量化,例如,“一个循环是向量化的”是什么意思?
当前回答
我会将向量化定义为给定语言的一个特性,其中如何遍历某个集合的元素的责任可以从程序员委托给语言提供的一些方法(例如,显式的元素循环)。
我们为什么要这么做呢?
Code readeability. For some (but not all!) cases operating over the entire collection at once rather than to its elements is easier to read and quicker to code; Some interpreted languages (R, Python, Matlab.. but not Julia for example) are really slow in processing explicit loops. In these cases vectorisation uses under the hood compiled instructions for these "element order processing" and can be several orders of magnitude faster than processing each programmer-specified loop operation; Most modern CPUs (and, nowadays, GPUs) have build-in parallelization that is exploitable when we use the vectorisation method provided by the language rather than our self-implemented order of operations of the elements; In a similar way our programming language of choice will likely use for some vectorisation operations (e.g. matrix operations) software libraries (e.g. BLAS/LAPACK) that exploit multi-threading capabilities of the CPU, another form of parallel computation.
请注意,对于第3点和第4点,一些语言(特别是Julia)允许这些硬件并行也使用程序员定义的顺序处理(例如for循环),但这是自动发生的,在使用语言提供的向量化方法时。
现在,虽然向量化有许多优点,但有时算法使用显式循环比向量化更直观地表达(可能我们需要求助于复杂的线性代数运算、单位和对角矩阵……所有这些都是为了保留我们的“向量化”方法),如果使用显式排序形式没有计算上的缺点,那么这个应该是首选。
其他回答
请看上面的两个答案。我只是想补充一下,想要做向量化的原因是,这些操作可以很容易地由超级计算机和多处理器并行执行,从而产生巨大的性能增益。在单处理器计算机上不会有性能提升。
我会将向量化定义为给定语言的一个特性,其中如何遍历某个集合的元素的责任可以从程序员委托给语言提供的一些方法(例如,显式的元素循环)。
我们为什么要这么做呢?
Code readeability. For some (but not all!) cases operating over the entire collection at once rather than to its elements is easier to read and quicker to code; Some interpreted languages (R, Python, Matlab.. but not Julia for example) are really slow in processing explicit loops. In these cases vectorisation uses under the hood compiled instructions for these "element order processing" and can be several orders of magnitude faster than processing each programmer-specified loop operation; Most modern CPUs (and, nowadays, GPUs) have build-in parallelization that is exploitable when we use the vectorisation method provided by the language rather than our self-implemented order of operations of the elements; In a similar way our programming language of choice will likely use for some vectorisation operations (e.g. matrix operations) software libraries (e.g. BLAS/LAPACK) that exploit multi-threading capabilities of the CPU, another form of parallel computation.
请注意,对于第3点和第4点,一些语言(特别是Julia)允许这些硬件并行也使用程序员定义的顺序处理(例如for循环),但这是自动发生的,在使用语言提供的向量化方法时。
现在,虽然向量化有许多优点,但有时算法使用显式循环比向量化更直观地表达(可能我们需要求助于复杂的线性代数运算、单位和对角矩阵……所有这些都是为了保留我们的“向量化”方法),如果使用显式排序形式没有计算上的缺点,那么这个应该是首选。
简而言之,矢量化意味着优化算法,使其能够利用处理器中的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也是如此。
向量化是将标量程序转换为矢量程序的术语。向量化程序可以从一条指令运行多个操作,而标量程序一次只能对操作数对进行操作。
从维基百科:
标量的方法:
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];
}
向量化在科学计算中被广泛使用,在科学计算中需要有效地处理大量数据。
在真正的编程应用中,我知道它在NUMPY中使用(不确定其他)。
Numpy (python中用于科学计算的包)使用向量化来快速操作n维数组,如果使用内置的python选项来处理数组,通常会较慢。
尽管有大量的解释,以下是NUMPY文档页中矢量化的定义
向量化描述了代码中没有任何显式的循环、索引等——当然,这些事情只是在优化的、预编译的C代码的“幕后”发生。向量化代码有很多优点,其中包括:
向量化的代码更简洁,更易于阅读 更少的代码行通常意味着更少的错误 代码更接近于标准的数学符号 (这使得正确编写数学代码更容易 构造) 向量化会产生更多的“python式”代码。没有 向量化,我们的代码就会充斥着低效的和 难以读取循环。