AMD Genoa平台AOCC+AMD-FFTW性能调优咨询(对比ICPX+MKL)
针对AMD Genoa平台优化AOCC+AMD-FFTW 3D FFT性能的方案
问题背景
我实现了一个带OpenMP多线程支持的3D原地FFT代码,基于FFTW。在双路AMD Genoa CPU的Ubuntu机器上,用AOCC 5.0+AMD优化的FFTW编译后,性能比icpx+MKL-FFT版本慢近一倍。
当前AOCC编译命令
clang++ bench_fftw.cpp -o bench_fftw -fopenmp -march=znver4 -O3 -flto -mavx512 -ffast-math -L/opt/AMD/amd-fftw/lib -lfftw3f_omp -lfftw3f -lm -I/opt/AMD/amd-fftw/include
运行环境变量
export OMP_NUM_THREADS=8 #for 1 CCD/NUMA export OMP_PLACES=cores #only using the physical core export OMP_PROC_BIND=close
对比的Intel编译命令
icpx bench_mkl.cpp -o bench_mkl -qopenmp -O3 -Ofast -ffast-math -axCORE-AVX2,CORE-AVX512 -qmkl
测试代码
#if 1 #include <fftw3.h> #else #include "fftw/fftw3_mkl.h" #endif #include <omp.h> #define N 1024 // Size of 3D cube (N x N x N) int main() { float *data; fftwf_plan plan_forward, plan_backward; fftwf_init_threads(); fftwf_plan_with_nthreads(omp_get_max_threads()); data = (float*)fftwf_malloc(sizeof(float) * N * N * (2*(N/2+1))); #pragma omp parallel for collapse(3) for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { for (int k = 0; k < N; k++) { data[i*N*N + j*N + k] = (i + j + k) % 2; } } } #if 0 plan_forward = fftwf_plan_dft_r2c_3d(N, N, N, data, (fftwf_complex*)data, FFTW_ESTIMATE); plan_backward = fftwf_plan_dft_c2r_3d(N, N, N, (fftwf_complex*)data, data, FFTW_ESTIMATE); #else plan_forward = fftwf_plan_dft_r2c_3d(N, N, N, data, (fftwf_complex*)data, FFTW_MEASURE); plan_backward = fftwf_plan_dft_c2r_3d(N, N, N, (fftwf_complex*)data, data, FFTW_MEASURE); #endif for(int i=0; i<50; i++){ fftwf_execute(plan_forward); fftwf_execute(plan_backward); } #pragma omp parallel for for (int i = 0; i < N * N * N; i++) { data[i] /= (N * N * N); } fftwf_destroy_plan(plan_forward); fftwf_destroy_plan(plan_backward); fftwf_free(data); fftwf_cleanup_threads(); return 0; }
调优方案
1. 编译选项优化
- 替换
-mavx512为-mavx512f -mavx512bw -mavx512dq -mavx512vl,明确指定Genoa支持的AVX-512子集,避免编译器启用不必要的指令集导致性能损失 - 用
-Ofast替代-O3,-Ofast包含-O3并进一步放宽数学优化,和Intel编译选项对齐 - 添加
-fwhole-program-vtables配合-flto,提升虚函数调用效率 - 增加
-mtune=znver4,强化针对Genoa的调度优化(-march已包含,但明确指定可增强效果)
调整后的编译命令示例:
clang++ bench_fftw.cpp -o bench_fftw -fopenmp -march=znver4 -mtune=znver4 -Ofast -flto -fwhole-program-vtables -ffast-math -L/opt/AMD/amd-fftw/lib -lfftw3f_omp -lfftw3f -lm -I/opt/AMD/amd-fftw/include
2. FFTW计划与线程配置优化
- 使用
FFTW_PATIENT替代FFTW_MEASURE,虽然计划生成时间更长,但能找到更适合Genoa架构的执行路径,尤其针对1024³这样的大尺寸FFT - 确认AMD-FFTW编译时启用了
--enable-avx512和--enable-openmp选项,确保库本身针对Genoa做了指令集优化 - 尝试将
OMP_PROC_BIND改为spread对比效果,Genoa的CCD内部缓存架构可能更适合特定线程分布 - 将数据初始化代码移到
fftwf_init_threads之前,减少线程环境对计划生成的干扰
3. 内存与NUMA优化
- 使用
numactl绑定进程到单个NUMA节点,避免跨节点内存访问:numactl --cpunodebind=0 --membind=0 ./bench_fftw - 尝试用
numa_alloc_local替代fftwf_malloc,手动控制内存分配在本地NUMA节点 - 调整3D循环遍历顺序,将
i->j->k改为k->j->i或j->k->i,利用空间局部性提升缓存命中率
4. 版本与库配置检查
- 升级AOCC到最新版本(如6.0+),AMD对Genoa的优化在后续版本中有显著提升
- 重新编译AMD-FFTW,指定
CC=clang CXX=clang++并添加--enable-sse2 --enable-avx --enable-avx2 --enable-avx512选项,确保库针对znver4架构编译 - 对比使用
libfftw3f_threads而非libfftw3f_omp,部分场景下FFTW原生线程库性能更优
5. 基准测试优化
- 增加FFT迭代次数到100+,减少初始化和收尾阶段的性能占比,更准确反映实际FFT性能
- 在迭代循环前后添加时间测量,排除数据初始化和归一化的时间干扰:
#include <chrono> // ... auto start = std::chrono::high_resolution_clock::now(); for(int i=0; i<100; i++){ fftwf_execute(plan_forward); fftwf_execute(plan_backward); } auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start); printf("Total FFT time: %lld ms\n", duration.count());
内容的提问来源于stack exchange,提问作者readonly
相关产品推荐
相关产品推荐

