许多CPU具有“向量”或“ SIMD”指令集,这些指令集将相同的操作同时应用于两个,四个或更多数据。现代的x86芯片具有SSE指令,许多PPC芯片具有“ Altivec”指令,甚至某些ARM芯片也具有称为NEON的矢量指令集。
“向量化”(简化)是重写循环的过程,以便与其同时处理(例如)数组的4个元素N / 4次,而不是处理数组的单个元素N次。
(我之所以选择4,是因为这是现代硬件最有可能直接支持的功能;“向量化”一词也用于描述更高级别的软件转换,您可以在其中完全抽象出循环并仅描述对数组而不是元素的操作。组成它们)
向量化和循环展开之间的区别: 考虑以下非常简单的循环,该循环将两个数组的元素相加并将结果存储到第三个数组中。
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”是您的编译器用来指定矢量指令的任何内部函数的占位符。请注意,某些编译器能够自动矢量化非常简单的这样的循环,通常可以通过编译选项启用它。更复杂的算法仍然需要程序员的帮助才能生成良好的矢量代码。