SIMD指令集(自动矢量化)

测试代码

// filename: test.cpp
#include 
#include 
#include 
#include 

using namespace std;

int main(int argc, char *argv[]) {
    struct timespec time_start={0, 0},time_end={0, 0};
    uint8_t bitmap[20240];
    int cost;
    clock_gettime(CLOCK_REALTIME, &time_start);
    for (int i = 0; i < 20240; ++i) {
        bitmap[i >> 3] |= 1 << (i&7);
    }
    clock_gettime(CLOCK_REALTIME, &time_end);
    cost = time_end.tv_nsec - time_start.tv_nsec;
    cout << "case COST: " << cost << endl;
    clock_gettime(CLOCK_REALTIME, &time_start);
    for (int i = 0; i < 20240; ++i) {
        bitmap[i >> 3] &= 1 << (i&7);
    }
    clock_gettime(CLOCK_REALTIME, &time_end);
    cost = time_end.tv_nsec - time_start.tv_nsec;
    cout << "case COST: " << cost << endl;
    int a = bitmap[1];
    // 下面这句话不注释会导致自动向量化失败,最终导致耗时增长100倍
    // std::cout << "TEST: " << a << endl;

}

编译环境

gcc 4.8.2 + CentOS release 4.3。

编译命令

gcc -lstdc++ -std=c++11 -O2 test.cpp
产出结果为a.out

结果

执行./a.out,COST在200纳秒以内。但是如果加上cout,COST在20~30微妙之间。

简单分析

cout函数涉及到了ostream,使用cout对数组bitmap的值进行输出,涉及到了io控制流,将使得编译器不会对其进行优化(及向量化执行)。

自动向量化(Auto Vectorization)条件

翻译自
SIMD指令集(自动矢量化)_第1张图片
  • 循环次数是可计算的
  • 没有反向循环承载依赖
  • 没有函数调用(除非是可向量化的数学函数,如sin,sqrt)
  • 线性的代码(仅有一个控制流:没有switch;但是if条件是可以的,如果它可以是现成masked assignments)
  • 如果是嵌套循环,向量化的一定是最内层的循环

自动向量化的常见技巧

例举了一些常用技巧,英文版貌似比中文版的内容多

常见的向量化技巧

自动向量化的编程指南

详细介绍了自动向量化成功和失败的各种情况。

自动向量化的编程指南

实际应用

在实际的工作中,使用gcc自动向量化是最方便的方法,但是自动向量化的条件其实是很苛刻的。尽管在demo代码上,可以很容易地做到向量化,但是在工作上要进行向量化,目前还没有做到。

你可能感兴趣的:(SIMD指令集(自动矢量化))