向量化是什么意思?

向量化是什么意思?

向量化的特性需要编译器和CPU都支持,让我们先来简单的了解一下向量化是如何工作的.假设我们有一个非常大的vector.简单的实现可以写成如下的方式:

std::vector<int> v {1, 2, 3, 4, 5, 6, 7 /*...*/};

int sum {std::accumulate(v.begin(), v.end(), 0)};

编译器将会生成一个对accumulate调用的循环,其可能与下面代码类似:

int sum {0};

for (size_t i {0}; i < v.size(); ++i) {
	sum += v[i];
}

从这点说起,当编译器开启向量化时,就会生成类似如下的代码.每次循环会进行4次累加,这样循环次数就要比之前减少4倍.为了简单说明问题,我们这里没有考虑不为4倍数个元素的情况:

int sum {0};
for (size_t i {0}; i < v.size() / 4; i += 4) {
	sum += v[i] + v[i+1] + v[i + 2] + v[i + 3];
}
// if v.size() / 4 has a remainder,
// real code has to deal with that also.

为什么要这样做呢?很多CPU指令都能支持这种操作sum += v[i] + v[i+1] + v[i+2] + v[i+3];,只需要一个指令就能完成.使用尽可能少的指令完成尽可能多的操作,这样就能加速程序的运行.

自动向量化非常困难,因为编译器需非常了解我们的程序,这样才能进行加速的情况下,不让程序的结果出错.目前,至少可以通过使用标准算法来帮助编译器.因为这样能让编译器更加了解哪些数据流能够并行,而不是从复杂的循环中对数据流的依赖进行分析.