资讯动态

Linux集群上安装Score-P与Scalasca:完整流程与避坑指南

发布时间:2026/9/20 2:51:23 来源:尧图企业网站定制
前阵子项目里跑一个 48 进程的 MPI 并行程序算完一次要 40 多分钟负载看着也还行但总感觉某些阶段在干等。查了一圈没头绪最后靠 Score-P 和 Scalasca 这套组合才把问题定位出来。这俩工具在 HPC 圈子里基本是标配尤其是对写科学计算程序的人来说Score-P 负责采集程序运行时的通信、同步、I/O 事件Scalasca 负责把采集到的海量数据缩减成一份能看懂的“堵车报告”。但说实话第一次装这对工具并不轻松依赖、版本匹配、环境变量各种坑我前后折腾了两天。这篇就把安装流程和踩过的坑完整整理出来给准备在 Linux 集群上装 Score-P 和 Scalasca 的朋友做个参考。整个流程适用于常见的 Linux 发行版CentOS/Rocky/UbuntuMPI 用 OpenMPI 或 MPICH 都可以编译器主流 GCC 就行。只要照着走最后能跑通一个 MPI 采样分析的全流程。1. 为什么非要装一对Score-P 与 Scalasca 的分工逻辑很多人刚接触这两个工具的时候第一反应是“这俩是不是重复了”。其实不是它们分别是性能分析流水线上的两个环节一个管采集一个管分析。1.1 Score-P给程序装“行车记录仪”Score-P 做的事情是插桩instrumentation把程序里关键的操作记录下来MPI 调用、OpenMP 同步、POSIX I/O、甚至硬件计数器。它支持 MPI、OpenMP、CUDA、HIP 这些主流并行模型也支持 MPIOpenMP 混合模式。程序插桩后运行会有大量事件写入 OTF2 格式的轨迹文件同时还会生成一个 profile 目录里面就是每个函数、每个通信调用的累计耗时。说成人话就是Score-P 相当于在车上装了个行车记录仪把整个运行过程每一秒发生了什么全录下来。但问题是录下来的东西太多一跑就是几个 GB 甚至几十 GB 的 trace 数据。这时候光靠人眼去翻根本不可能所以必须有下一步。1.2 Scalasca自动剪出“事故点”和“堵车点”Scalasca 读取 Score-P 生成的 trace 数据做自动的并行性能分析。它最核心的能力是识别“等待状态”比如某个进程卡在 MPI_Recv 上等别的进程发数据Scalasca 能判断出这是不是因为负载不均衡或者因为某一段关键路径拖了后腿。分析结果会输出 Cube 格式的报告后缀是 .cubex打开之后可以看到每个函数、每个调用的时间花销、通信开销和同步开销。类比来说Scalasca 就是那个看行车记录仪的“事故分析专员”。它不关心每一帧视频只关心哪里堵了、哪里撞了、因为什么原因撞的。这正好弥补了 Score-P 只管记录不管分析的短板。1.3 为什么两个都得装以及安装顺序单独装 Score-P 也能拿到海量事件但手工从 trace 里找性能瓶颈效率极低。单独装 Scalasca 却没有任何数据源因为它的输入就是 Score-P 的产物两者是上下游关系。所以在安装顺序上一定是先装 Score-P再装 ScalascaScalasca 的 configure 阶段需要识别 Score-P 的安装路径。版本对应也值得留意。我的建议是别拿太老的 Score-P 配新 Scalasca反之亦然。以我这次为例用的是 Score-P 8.0 系列配 Scalasca 2.6配套的 OTF2 和 Cube 版本都会被 Score-P 构建过程自动处理好整体很稳定。2. 装之前先清点底料依赖环境与版本取舍这套工具本身不是特别重但它依赖的东西不少而且很多依赖是“少了不行、版本不对也不行”。我建议在下载源码之前先花十分钟把环境检查一遍。2.1 必须要有的基础工具我这里列的都是硬性要求缺哪个装哪个不要抱着“先试试看”的侥幸心理否则 configure 阶段就会各种报错。工具作用缺失时的典型现象GCC 套件gcc/g/gfortran编译 C/C/Fortran 代码configure 报找不到 C/C 编译器OpenMPI 或 MPICH 全家桶并行环境提供 mpicc/mpif90configure 报找不到 MPI wrapperautoconf / automake / libtool源码构建系统解压后构建脚本无法生成 Makefileflex / bison生成 OTF2 解析器代码OTF2 构建时报语法生成器缺失perl / python3部分辅助脚本依赖安装后 scorep-info 等命令异常wget / curl下载源码包没太多好说的这里特别提醒一点如果系统里已经装了 Intel oneAPI我建议整套都用 Intel 编译器icc/icpc/ifort不要 GCC 和 Intel 混着来。混用编译器最常见的后果是Score-P 编译时检查 CPU 特性、ABI 时出现不一致之后链接 MPI 程序时各种诡异报错。一旦选定了编译器指挥棒后面 MPI、PAPI 能匹配就要尽量匹配。2.2 可选依赖和我的建议有几个可选依赖我简单说说我的看法PAPIPerformance Application Programming Interface用来读取硬件计数器比如缓存未命中、浮点运算次数。对纯 MPI 通信分析来说不是必需的但如果你是做性能调优、比较不同算法版本有 PAPI 数据会更有说服力。libunwind用于采样回溯。如果想用 Score-P 的 sampling 方式分析需要它。这个库版本要求有点玄学太老的新版本不认太新的有时也有兼容问题。我的建议是如果只需要常规的 MPI/OpenMP 事件插桩可以暂时不装。CUDA / HIP 相关 SDK只在你需要分析 GPU 程序时才需要。没有就 configure 时不加相关参数即可。zlib一般系统都会有没有就装一下Cube 报告写压缩格式时用得上。如果拿不准版本组合可以参考我这次实际用的组合GCC 12.2 OpenMPI 4.1.5 Score-P 8.0 Scalasca 2.6。这套组合在 x86_64 架构上非常稳社区里也常见。2.3 没有 root 权限怎么办如果你是在共享集群上安装没有 sudo 权限完全可以装到用户目录。做法就是 configure 的时候把 --prefix 指定到 $HOME/opt/scorep 这样的位置其他步骤没有任何区别。唯一要留意的是某些依赖库比如 PAPI 如果自己编译如果安装在非标准路径configure 阶段可能找不到头文件或库文件。解决办法是设置export CPPFLAGS-I$HOME/opt/include export LDFLAGS-L$HOME/opt/lib把依赖头文件和库文件路径手动告诉 configure。这个小技巧比各种 --with-xxx 参数灵得多。3. 核心安装过程configure、make 的每个关键开关怎么选现在进入正题。下面这套命令我已经在实际环境里跑通过直接复制改一下路径就行。3.1 下载源码Score-P 的官方下载入口在 www.score-p.org 的 Download 页会跳转到源码仓库。Scalasca 在 www.scalasca.org 的 Software 页。这两个网站偶尔会有维护窗口期如果访问慢可以找学校或者实验室的镜像源。下载时认准 tar.gz 包即可。wget https://www.score-p.org/release/scorep/8.0/scorep-8.0.tar.gz wget https://scalasca.org/software/scalasca-2.x/release/scalasca-2.6.tar.gz3.2 Score-P 编译安装解压并进入目录tar xzf scorep-8.0.tar.gz cd scorep-8.0然后 configure。我先给出一份最精简但能用的配置./configure \ --prefix/opt/scorep/8.0 \ --with-mpi/opt/openmpi/4.1.5 \ --enable-shared解释一下这些参数--prefix安装路径。强烈建议把版本号写进路径机构内部升级多版本时切换非常方便。--with-mpi指定 MPI 的安装根目录。这里也可以不写让 configure 自己找 mpicc。但我遇到过 PATH 里 mpicc 存在但版本不对导致分析结果异常的情况所以显式指定更稳妥。--enable-shared生成动态库。如果不指定默认可能只生成静态库后面链接应用时会麻烦很多。如果你的环境里有 PAPI 并且希望纳入硬件计数器--with-papi/opt/papi如果你明确不需要某些组件可以用--without-papi这类参数关掉configure 过程更清爽也能省去不少依赖排查时间。关于 Score-P 源码包内捆绑的 OTF2、OPARI2、Cube 这几个核心组件configure 默认会在源码树内自动构建它们。这其实是官方非常贴心的设计因为这几个组件之间版本耦合度高手动分开装很容易出现版本不匹配。所以我不建议自己单独去装 OTF2除非你有特殊原因。配置没问题的话接着编译make -j$(nproc) make install-j$(nproc)的意思是让 make 用所有 CPU 核心并行编译。如果机器内存紧张可以降为-j4或-j2避免内存被打满导致编译进程被内核杀死。编译需要几分钟到十几分钟不等。装完看一下目录结构应该包含 bin、lib、include、share 等ls /opt/scorep/8.0其中 bin 下最重要的几个命令是scorep、scorep-config、scorep-info。3.3 Scalasca 编译安装Scalasca 的 configure 比 Score-P 简单核心是让它找到 Score-P 的安装位置tar xzf scalasca-2.6.tar.gz cd scalasca-2.6 ./configure \ --prefix/opt/scalasca/2.6 \ --with-score-p/opt/scorep/8.0 make -j$(nproc) make install--with-score-p就是告诉它“我的 Score-P 装在这里”。Scalasca 内部会调用 Score-P 的相关工具和 OTF2 库所以如果找不到configure 会直接失败。这里还有个小细节如果之前设置过 CPPFLAGS 或 LDFLAGS 指向第三方依赖目录在 configure 和 make 全程保持这两个变量一致避免中途切换环境变量导致部分目标文件重新编译。整个安装过程如果没报错最后make install完成后bin 目录下会有scalasca、scalasca-examine、scalasca-analyze等命令。3.4 如何快速确认装上了不要急着写测试程序先用版本命令确认基本可用性/opt/scorep/8.0/bin/scorep --version /opt/scalasca/2.6/bin/scalasca --version能正常打印出版本号说明可执行文件层面没问题。接下来要处理环境变量否则系统找不到这些命令。4. 环境变量与 site file装完不等于能用我见过不少人栽在这一步。装完之后直接敲scorep却提示 command not found或者编译运行时报找不到动态库。这不是没装好而是环境变量没配。4.1 PATH 和 LD_LIBRARY_PATH 为什么是第一步PATH 决定 shell 能不能找到可执行文件LD_LIBRARY_PATH 决定运行程序时动态链接器能不能找到 .so 文件。这两个缺一不可。以我的安装路径为例在~/.bashrc末尾加入export PATH/opt/scorep/8.0/bin:/opt/scalasca/2.6/bin:$PATH export LD_LIBRARY_PATH/opt/scorep/8.0/lib:/opt/scalasca/2.6/lib:$LD_LIBRARY_PATH然后source ~/.bashrc此时执行scorep --version就正常了。需要提醒的是如果你用的是共享集群很多集群默认 shell 是 bash 但登录脚本用的是模块系统那么把环境变量直接写进 .bashrc 可能不如写 modulefile 规范。4.2 更规范的 modulefile 方案在大型集群上各个用户、各个项目可能用不同版本的编译器、MPI 和性能工具靠 .bashrc 硬编码路径迟早会打架。module 系统Lmod/Environment Modules可以很好解决这个问题。写一个简单的 modulefile 示例如下#%Module1.0 set version 8.0 prepend-path PATH /opt/scorep/8.0/bin prepend-path LD_LIBRARY_PATH /opt/scorep/8.0/lib set scalasca 2.6 prepend-path PATH /opt/scalasca/2.6/bin prepend-path LD_LIBRARY_PATH /opt/scalasca/2.6/lib这样用户只需要module load scorep/8.0 scalasca/2.6就能完整切换环境。管理多版本时这个方案远远优于手工 export。4.3 site config 配置默认编译器与 MPIScore-P 提供了一个 site config 机制用来预设默认的编译器、MPI 环境等。安装完成后一般会生成一个示例配置位置通常在$HOME/.scorep/site-config或者安装目录的 etc 下面。这个文件里可以指定CCgcc CXXg MPICCmpicc MPICXXmpicxx它的作用是当你执行scorep mpicc -o test test.c时里面的mpicc到底由哪个 MPI 提供可以在 site config 里锁死。如果集群上同时装了 OpenMPI 和 MPICH这个文件能防止你手误用到错误的 mpicc。我第一次装的时候不太懂这个机制结果 Score-P 用的 MPI 和编译应用用的 MPI 不一致运行时报了一堆奇怪的 MPI 层错误。需要说明的是site config 的具体字段名在不同版本里略有差异最靠谱的办法是安装后查看生成的示例配置照着注释改。不用死记硬背。5. 拿一个真实 MPI 程序走通全流程安装配置都完成后最关键的验证环节来了。我们要编译运行一个 MPI 程序让 Score-P 和 Scalasca 真正跑一遍确认整条链路是通的。5.1 写一个简单但真实的测试程序我用的是 MPI_Allreduce 循环模拟真实程序里常见的全局通信密集场景。这段代码故意让它产生大量通信方便之后 Scalasca 分析出东西。#include mpi.h #include stdio.h #include stdlib.h int main(int argc, char *argv[]) { int rank, size; int n 1024 * 1024; double *buf; MPI_Init(argc, argv); MPI_Comm_rank(MPI_COMM_WORLD, rank); MPI_Comm_size(MPI_COMM_WORLD, size); buf (double *)malloc(n * sizeof(double)); for (int i 0; i n; i) { buf[i] (double)rank; } for (int t 0; t 100; t) { MPI_Allreduce(buf, buf, n, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); } printf(rank %d/%d done\n, rank, size); free(buf); MPI_Finalize(); return 0; }5.2 用 scorep 包裹编译与运行Score-P 的用法非常巧妙它不强制你修改 Makefile只需要在编译命令前面加上 scorep 前缀scorep --mppmpi --threadnone mpicc -o test_mpi test_mpi.c解释一下参数--mppmpi告诉 Score-P 这是 MPI 程序需要链接 MPI 相关的插桩适配器。--threadnone这里不插桩 OpenMP 线程因为测试程序是纯 MPI。mpicc真正的编译命令后面跟着的-o test_mpi test_mpi.c原样传给 mpicc。编译成功后生成的 test_mpi 是经过插桩的。接下来正常运行即可mpirun -np 4 ./test_mpi运行结束后当前目录下会出现scorep_test_mpi_4_sum具体后缀可能存在差异这种带前缀的目录里面包含 OTF2 轨迹文件和 profile 数据。看到这个目录说明 Score-P 的采集链路已经通了。5.3 scalasca -examine 出报告拿到 trace 数据后Scalasca 登场scalasca -examine -s scorep_test_mpi_4_sum-s表示只输出 summary 报告不导出全量逐事件的详细分析。这是最快也是最常用的手段。执行完后目录里会多出profile.cubex之类的 Cube 报告文件。把这个 cubex 文件下载到本地用 Cube GUICube 是一个跨平台可视化工具可以在本地安装打开能直观看到各函数的累计时间占比MPI 通信时间占总时间的比例同步开销排名每个 rank 的负载均衡情况。以我那次 48 进程测试为例跑完之后一眼就能看到 MPI_Allreduce 占掉了 34% 的墙钟时间而其中一个 rank 因为计算量偏大导致其他 rank 在同步点空等。这个结论如果靠猜不知道要猜多久。6. 我踩过的坑从报错到解决的完整排查链路装这俩工具最常见的不是装不上而是装的时候各种报错看着吓人其实大多数就几个固定原因。我把实际遇到的几个坑和完整排查过程写出来。6.1 configure 根基问题MPI wrapper 找不到第一次尝试时configure 输出一大片最后卡在checking for MPI compiler wrappers... not found。当时我的第一反应是 MPI 没装好但which mpicc明明能输出路径。仔细想了一下问题出在 PATH 顺序上。系统里存在一个老版本 MPICH 的 mpicc 在 PATH 前面而 Score-P configure 默认去找的 OpenMPI 的 mpicc 被挡在后面。解决办法有两个一是--with-mpi/opt/openmpi/4.1.5显式指定路径二是调整 PATH把 OpenMPI 的 bin 放到最前面。这事的教训是configure 日志一定要看完整别只看最后一行失败信息。报错前面往往就有线索。6.2 运行时 so 文件找不到LD_LIBRARY_PATH 缺失Score-P 装好后立刻自己写了个测试程序编译通过但一运行就报error while loading shared libraries: libscorep_adapter_mpi_event.so: cannot open shared object file这个错误很典型就是动态链接器找不到 libscorep 的库目录。我的第一反应是 LD_LIBRARY_PATH 没配好检查后发现确实漏了 /opt/scorep/8.0/lib。但这里还有个更隐蔽的情况即使 LD_LIBRARY_PATH 配好了到集群计算节点运行时如果计算节点用的登录脚本不包含这个 export照样找不到。所以要么把所有节点的 /etc/profile.d 统一配置要么使用 modulefile 并且在提交作业的脚本里显式module load。排查这类问题最直接的工具是 lddldd test_mpi | grep scorep如果显示 not found那就是动态库搜索路径的问题对照 4.1 节配置即可。6.3 新版 GCC 编译旧版源码报错还有一个高频坑拿到一份老版本的 Score-P比如 6.x用 GCC 13 或 GCC 14 编译configure 过了make 到一半报 C 编译错误说什么某个类没有成员函数。说白了就是老代码没有跟上新标准C17/20的变化。遇到这种情况我的建议是别花大量时间去看代码兼容性直接换成配套的新版本工具链。Score-P 7.x 以上对较新的 GCC 支持就好很多。HPC 工具的版本组合非常重要就像齿轮齿距对不上就得换整套。如果你因为某些原因必须用旧版 Score-P可以尝试在 configure 时加上CPPFLAGS-stdc14这个参数能解决一部分旧源码的编译问题但不保证全部管用。最好还是升级源码包版本。6.4 集群多节点路径不一致还有一次我遇到的情况比较“玄”程序在登录节点跑得好好的一上计算节点就提示找不到 scorep 相关命令或者库。排查到最后发现原因其实很朴素可执行文件和相关库装在 /opt 下面但那几个计算节点和登录节点的 /opt 并不是共享存储路径压根不存在。解决方式有三条路安装到共享存储路径比如所有节点都挂载的 /shared 或家目录用集群管理软件如 pdsh把所有节点的 /opt 环境同步一遍用模块系统统一管理在作业脚本里让每个节点加载同一个 modulefile。我个人的习惯是第一种装到共享家目录或者共享项目目录配合 modulefile 使用一劳永逸。6.5 一个容易忽略的细节编译优化级别最后说一个很多人不会注意到但会影响分析结果的点如果程序本身是用-O3 -marchnative编译的插桩后测量到的通信时间比例和你实际优化的目标并不完全一致。这是正常现象因为插桩本身会带来额外开销但通信事件和被测量函数的比例关系一般还是准的。我自己在对比优化前后版本的性能时统一用-O2作为测量基准不做 aggressive 优化这样结果更可复现。分析完确定瓶颈再回到真正的编译优化里去做调优。这套工具装好之后后续最实用的工作流就是先跑一个小规模测试验证链路再上全规模采集每次分析前先把 profile 摘要看一眼确实可疑再用 Scalasca 的完整事件分析去挖细节。这个顺序能省掉大量不必要的数据量。我第一次装完就急着拿全集群 128 个节点去跑结果产生的 trace 数据有几十 GB分析时等了大半天还差点把共享存储挤爆。后来学乖了先用 4 个进程验证再慢慢扩大规模。也希望你少走这段弯路。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价