You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:55:58