如何在Ubuntu上构建编译LLVM和ISPC,以及Ubuntu上ISPC的使用方法
之前一直在 Mac 上使用 ISPC,奈何核心/线程太少了。最近想在 Ubuntu 上搞搞,但是 snap 安装的 ISPC不知道为什么只能单核,很奇怪,就想着编译一下,需要 Clang 和 LLVM。但是 Ubuntu 很搞,他的很多软件版本是和系统版本挂钩的,默认安装的是 14,这样安装可能会缺东西。没办法,搞吧,顺道研究下这两个的编译和使用。
本文并不是很详细,属于备忘录性质。
准备工作
首先安装需要的工具:
sudo apt-get install git curl cmake xz-utils m4 flex bison python3 libtbb-dev g++-multilib
LLVM
虽然官方文档里说可以用 APT 安装,但是版本不太对。虽然 LLVM 编译需要很长时间,如果你的核心数不够多,那么可以用官方脚本安装,然后自己手动改名称,嗯,也挺麻烦的。
不过现在绝大部分处理器编译的速度都还可以,毕竟大小核心加起来基本上都有十几个了。我曾经在 6 核处理器上编译了一晚上,太慢了。
需要注意 LLVM 编译时间很长而且选项很复杂,这里只说我们需要的 LLVM、Clang 和 LLD,命令如下:
cmake -S llvm -B build -G 'Unix Makefiles' -DLLVM_ENABLE_PROJECTS="clang;lld" -DCMAKE_BUILD_TYPE=Release
这里使用全部的线程构建:
make -j$(nproc)
然后安装命令如下(就是放到该放的地方):
cmake --build . --target install
不过没有复制FileCheck
,所以自己挪一下(不知道是我执行其他命令的缘故还是就是这个命令没有操作,反正我手动挪了):
sudo cp FileCheck /usr/local/bin/FileCheck
安装完之后看看llvm-config
版本和位置:
$ which llvm-config
/usr/local/bin/llvm-config
$ llvm-config --version
21.0.0git
你也可以对clang
等进行相关检查。
如果你想看更多编译情况可以看我的另外一篇博客:
ISPC
首先克隆仓库:
git clone https://github.com/ispc/ispc.git
不建议使用官方的脚本,因为网络问题,下载太慢了。
然后开始编译(不要在 ISPC 项目目录下运行,因为是单独生成build-ispc
文件夹存放生成内容):
cmake -B build-ispc ispc
然后开始构建(不要用官方文档里的cmake --build build-ispc
,这个只能使用一个核心,太慢了):
cd build-ispc
make -j$(nproc)
然后把生成二进制目录添加到PATH
环境变量里:
export PATH="$PATH:<自己改目录>/build-ispc/bin"
关于这部分如果你不熟悉,那么可以看看 macOS在终端上如何直接使用脚本或者下载的程序 - ZhongUncle CSDN。
最后看看ispc
版本:
$ ispc --version
Intel(r) Implicit SPMD Program Compiler (Intel(r) ISPC), 1.27.0dev (build commit f988909621671856 @ 20250313, LLVM 21.0.0)
使用 ISPC
这里需要注意,ispc
编译的时候使用--pic
选项:
ispc SGEMM_kernels.ispc -O3 -o SGEMM_kernels_ispc.o -h SGEMM_kernels_ispc.h --target=avx2-i32x16 --pic
--pic
这个选项太冷了,我是翻文档翻出来的,绝了。
然后再使用clang++
、g++
之类的通用编译器编译:
clang++ -O3 SGEMM_main.cpp SGEMM_kernels_ispc.o ../common/tasksys.cpp
否则可能会出现如下问题:
/usr/bin/ld: SGEMM_kernels_ispc.o: relocation R_X86_64_32 against `.text' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: failed to set dynamic section sizes: bad value
collect2: error: ld returned 1 exit status
正确编译后,运行看看:
$ ./a.out 2048 16 4096
Usage: SGEMM (optional)[ispc iterations] (optional)[[Matrix A Rows] [Matrix A Columns/ matrix B Rows] [Matrix B Columns]]
./a.out
ispc iterations = 500[default], Matrix A Rows = 2048, Matrix A Columns/ matrix B Rows = 16, Matrix B Columns = 4096
SGEMM_naive_withTasks 5.4232 millisecs 49.4920 GFLOPs Validation: valid.
SGEMM_tileShuffle_withTasks 2.7940 millisecs 96.0635 GFLOPs Validation: valid.
SGEMM_tileNoSIMDIntrin_withTasks 1.4964 millisecs 179.3685 GFLOPs Validation: valid.
SGEMM_tileBlockNoSIMDIntrin_withTasks 1.0402 millisecs 258.0334 GFLOPs Validation: valid.
SGEMM_tileBlockNoSIMDIntrin_2_withTasks 1.0505 millisecs 255.5048 GFLOPs Validation: valid.
这时候 CPU 利用率需要满载,如下(注意看./a.out 2048 16 4096
这行):
题外话
ISPC 是我学过的第一个并行计算语言,并且付出了很大精力去研究和学习。
虽然有感情,但是我并不推荐使用 ISPC,原因很简单,Intel 修改 ISPC 太快太多了,再加上文档并不完善。这样会浪费大量时间在研究和更新上,而不是写代码上,太麻烦了。
希望能帮到有需要的人~