Faiss(16):编译时添加对AVX512指令的支持

1. 说明

在对Faiss CPU profiling分析时对libfaiss.o进行反汇编发现该程序没有用到avx512指令进行优化,而该指令在进行浮点运算时相比其他指令集会有更好的效率和速度,故在此记录将AVX512指令集添加进程序的编译过程。

2. 编译OpenBLAS

openblas 是一个开源的矩阵计算库,包含了诸多的精度和形式的矩阵计算算法。就精度而言,包括float和double,两种数据类型的数据,其矩阵调用函数也是不一样。不同矩阵,其计算方式也是有所不同,(姑且认为向量也是一维矩阵),例如,向量与向量之间的计算,向量与矩阵之间的计算,矩阵与矩阵之间的计算。
Faiss在编译时就要用到这个库,所以在编译这个库时需要支持AVX512。

2.1 OpenBLAS判断CPU架构的规则

根据CPU架构的不同,OpenBLAS支持多种不同指令集,它判断当前CPU架构的步骤如下:

1. 验证GCC或clang版本

OpenBLAS支持使用GCC和clang两种编译器,对GCC的版本要求是大于gcc-6,clang的要求是大于clang-5。否则编译器不支持AVX512指令。
如getarch.c

#if (( defined(__GNUC__)  && __GNUC__   > 6 && defined(__AVX2__)) || (defined(__clang__) && __clang_major__ >= 6))
#else
#define NO_AVX512
#endif

2. 读取CPU的vendor, family, exfamily, model, exmodel

通过上述信息可以判断出CPU属于哪一系列,如我使用的vendor=1, family=6, exfamily=0, model=5, exmodel=5。
cpuid_x86.c/get_cpuname()

family   = get_cputype(GET_FAMILY);
exfamily = get_cputype(GET_EXFAMILY);
model    = get_cputype(GET_MODEL);
exmodel  = get_cputype(GET_EXMODEL);

vendor = get_vendor();

3. 通过cpuid(7), xgetbv操作判断是否支持AVX512指令

cpuid_x86.c

int support_avx512(){
#if !defined(NO_AVX) && !defined(NO_AVX512)
  int eax, ebx, ecx, edx;
  int ret=0;

  if (!support_avx()) 
    return 0;
  cpuid(7, &eax, &ebx, &ecx, &edx);
  if((ebx & 32) != 32){
      ret=0;  //OS does not even support AVX2
  }
  if((ebx & (1<<31)) != 0){
    xgetbv(0, &eax, &edx); 
    if((eax & 0xe0) == 0xe0)
      ret=1;  //OS supports AVX512VL
  }
  return ret;
#else
  return 0;
#endif
}

2.2 重新编译OpenBLAS

由于我用的Ubuntu16.04 使用的GCC版本是5.4.0版本,所以OpenBLAS认为CPU不支持AVX512指令,编译出来的库文件为libopenblas_haswellp-r0.3.8.dev.so,如下图所示:
Faiss(16):编译时添加对AVX512指令的支持_第1张图片

1. 重新安装编译器

# 安装gcc-7
sudo apt-get install gcc-7, g++-7

# 安装gfortran-7
sudo apt-get install gfortran-7

# 修改默认属性
cd /usr/bin
rm -f gcc, g++, gfortran
ln -s gcc-7 gcc
ln -s g++-7 g++
ln -s gfortran-7 gfortran

2. 重新编译OpenBLAS

make clean
make FC=gfortran
make install

操作完成后会将生成的库文件添加进/opt/OpenBLAS/lib目录中。如下图所示:

3. 重新编译Faiss

1. 修改编译参数

vim makefile.inc
CPUFLAGS     = -mpopcnt -msse4
# 修改为
CPUFLAGS     = -mpopcnt -msse4 -mavx512f -mavx512cd

2. 重新编译

make clean
make -j32
make install

3. 反汇编验证

objdump -S libfaiss.o > objdump_libfaiss.txt

返汇编代码可以看到包含诸如vmovss等AVX512指令:

Faiss(16):编译时添加对AVX512指令的支持_第2张图片

你可能感兴趣的:(Faiss)