Lukas Krenz, Mathias Wagner, Sr. Developer Technology Engineer
| S72978 | GTC 2025
超级芯片的构建模块
复用他人的工作
-O3 -mcpu=native -ffp-contract=fast-mcpu=neoverse-v2+crypto+sha3+sm4+sve2-aes+sve2-sha3+sve2-sm4 标志会启用所有功能(可能不检测加密扩展)。-Ofast,但在移植前请务必检查其准确性。-ffp-contract=off 来禁用浮点运算收缩(例如,FMA)。-flto 来启用链接时优化。-fsigned-char 或 -funsigned-char,具体取决于开发者的假设。-fno-stack-arrays 中受益。使用默认接口以实现性能可移植性
$ perf stat -I 100 -o perf.json --json \
-e 'duration_time,{nvidia_scf_pmu_0/cmem_rd_data/,nvidia_scf_pmu_0/cmem_wr_total_bytes/}'
(32 * cmem_rd_data + cmem_wr_total_bytes) / duration_time / 1e9时间线视图
nsys profile ./app*.nsys-rep 文件。标记您的代码
#include <nvtx3/nvToolsExt.h>
void congrad_64()
{
nvtxRangePush(__func__); // Range around the whole function
for (int i = 0; i < 6; ++i)
{
nvtxRangePush("loop range"); // Range for iteration
// Do ab iteration
nvtxRangePop(); // End the inner range
}
nvtxRangePop(); // End the outer range
}
收集核心性能指标
使用以下命令查看可用的核心指标:
nsys profile --cpu-core-metrics=help
收集 uncore 性能指标
使用以下命令查看可用的套接字(socket)级别指标:
nsys profile --cpu-socket-metrics=help
链接:https://github.com/brendangregg/FlameGraph
使用 Nsight Systems
- 在 Nsight Systems 安装目录下的 Scripts/Flamegraph 目录中
- nsys profile -o report ./app
- python3 stackcollapse_nsys.py report.nsys-rep | ./flamegraph.pl > result_flamegraph.svg
使用 perf
- perf record -a -g ./app
- perf script | stackcollapse-perf.pl > out.perf-folded
- flamegraph.pl out.perf-folded > perf.svg
该工具可以帮助开发者理解编译器对源代码所做的具体优化和转换,通过并排显示源代码、生成的汇编代码以及编译器优化后的代码,可以直观地看到向量化等优化的效果。
代码来自 Coral 基准测试套件的 HACCmk 基准测试,来源:https://asc.llnl.gov/coral-benchmarks
请按顺序遵循这些建议,例如,优先选择自动向量化而不是内联函数(intrinsics)。
编译器指令:例如 OpenMP
- #pragma omp parallel for simd
- #pragma vector always
库 (Libraries)
- NVIDIA Math Libraries (NVPL)
- Arm Performance Library (ArmPL)
- 开源科学库 (BUS, FFTW, PETSc, etc.)
库的类别包括:BLAS, LAPACK, PBLAS, SCALAPACK, TENSOR, SPARSE, RAND, FFTW
内联函数 (Intrinsics - ACLE)
- https://developer.arm.com/architectures/instruction-sets/intrinsics
- https://developer.arm.com/documentation/100987/latest
- https://arxiv.org/abs/1902.09544
汇编 (Assembly)
- 参考 https://developer.arm.com/documentation/ddi0584/latest (Arm®v8-A 架构的可扩展向量扩展)
通常在较高的优化级别下启用。
- 使用一些更激进的选项,如 -Ofast (例如,归约操作)。
诊断标志可以让你看到编译器做了什么以及没有向量化的部分。
- LLVM:
- -Rpass(-missed|-analysis)=loop-vectorize
- GCC:
- -fopt-info-vec-(optimized|missed|all|note)
- NVIDIA compilers:
- -Minfo=vect
查看输出和生成的代码 → 使用 Compiler explorer / Godbolt。
在适用的情况下,在 C / C++ 中使用 restrict 指针。
使用 pragmas 来指导编译器(取决于所使用的编译器)。
- #pragma GCC ivdep
- #pragma clang loop vectorize
- #pragma omp simd
Arm 的内存模型是弱序 (weakly-ordered) 的,与 x86 的内存模型不同:加载/存储操作可能在运行时被 CPU 重排。
写入操作对其他线程的可见顺序可能不同。
许多程序使用顺序一致性 (sequential consistency) 来在线程间传递消息 (例如, std::atomic with std::memory_order_seq_cst)。
对于线程间的同步,release/acquire 语义可能就足够了。
使用较弱的内存顺序可以提高性能,但也可能引入错误。
如果不确定:请使用库中的同步原语。
这是一个复杂的话题,更多上下文请参考 Herb Sutter 的文章:https://herbsutter.com/2013/02/11/atomic-weapons-the-c-memory-model-and-modern-hardware/
主要 takeaways
也欢迎访问我们今天下午 3:00 – 3:50 PM 的 CWE:
如何在 NVIDIA Grace CPU 上运行和优化您的工作负载 [CWE73338]