对抗 Intel MKL ICC 的黑魔法防御术

MKL 和 ICC 可谓是 Intel 的两大黑魔法,又神秘又难用,但确实快。这两年来 Intel 把黑魔法都收归到 OneAPI 旗下,
也做了一些简化安装、使用的操作,于是就整理了一下目前的使用方法。

安装

Base Toolkit 官方下载页
HPC Toolkit 官方下载页
分别下载两个安装包,其中 HPC Toolkit 需要先安装 Base Toolkit,包含 MKL 和 ICC、ICX(ICC 的 Clang 版)。
这边推荐用 offline 安装方式,下载速度“高达” 1MB/s,比 apt 的 500KB/s 快了很多(

本地安装的时候,终端窗口要开大点,不然会报错说无法设置为 CLI 模式云云。

默认会安装到 /opt/intel 路径下。

使用(2022 以前版本)

个人目前的工作流是 vscode + cmake,这应该也是比较常见的工作流,故以下介绍这一工作流的使用方法。

vscode 上目前有一个 Intel 官方的 OneAPI 环境配置插件(尽管没什么人用),可以单独为 vscode 配置环境。
不过作为服务器管理来说,肯定不能要求所有人都使用 vscode,并且如果不配置环境,连 ICC 都找不到,
因此肯定要进行全局配置。

配置方法倒是很简单,在要启用 OneAPI 的用户的 ~/.bashrc 中加入 source /opt/intel/oneapi/setvars.sh 即可。

cmake 设置

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -fast -ansi-alias -fopenmp -finline -funroll-loops -m64 -fma -mkl")

vscode 项目配置

.vscode/c_cpp_properties.json

{
"configurations": [
{
"name": "Linux",
"compilerPath": "/opt/intel/oneapi/compiler/latest/linux/bin/icpx",
"cStandard": "gnu11",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-clang-x64",
"compileCommands": "${workspaceFolder}/build/compile_commands.json"
}
],
"version": 4
}

注意不要让 cmake 插件接管,即删除 configurationProvider 配置项。这里只要调用 cmake 生成的 compile_commands.json 就能正确设置 intellisense 了。

.vscode/settings.json

{
"cmake.configureSettings": {
"CMAKE_C_COMPILER": "icc",
"CMAKE_CXX_COMPILER": "icpc",
}
}

有意思的是,调用 MKL 的项目用 icx 编译的话容易找不到 vsl 相关的函数定义,但 intellisense 用 icc 又找不到相关库,
所以我们编译使用 icc,intellisense 使用 icx。

最后要让 F7 能够调用 icc 的话,就用 Ctrl+Shift+P 打开 CMake: Edit User-Local CMake Kits,加入:

{
"name": "C++ Intel(R) 64 Compiler Classic",
"compilers": {
"C": "/opt/intel/oneapi/compiler/latest/linux/bin/intel64/icc",
"CXX": "/opt/intel/oneapi/compiler/latest/linux/bin/intel64/icpc"
},
"keep": true
},
{
"name": "Clang Intel(R) 64 Compiler Classic",
"compilers": {
"C": "/opt/intel/oneapi/compiler/latest/linux/bin/clang",
"CXX": "/opt/intel/oneapi/compiler/latest/linux/bin/clang++"
},
"keep": true
},

在底栏选择新增的 Intel kit 即可。

调试设置

icc 似乎并不支持直接设置 Debug 参数,这里提供针对调试的 cmake 参数:参考 NASA 教程

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -march=native -fopenmp -mkl")

这样就可以在 vscode 调试中查看 SIMD 寄存器的值了。

使用(2022)

2022 的版本中加入了许多对 cmake 的支持,不过尚未仔细研究。

常用参考

Intel 指令集函数说明

注意,有些指令顶着 AVX2 的帽子,但其实是 AVX512,譬如 _mm256_cmpneq_epi8_mask

调试技巧

valgrind 目前版本 3.18.1,2021-10-15 还只最高支持 AVX2 指令集,也就是说 AVX512 尚不可用,所以铁报错。