0%

Intel oneAPI hackathon:FFT 性能对比

有幸参加了 Intel 组织的 oneAPI 黑客松大赛,使用 oneMKL 提供的接口,对 FFT 计算进行了加速,特此记录。

代码库

https://github.com/jywhy6/oneapi_hackathon

安装依赖

oneMKL

CMake

  • CMake 是一个开源的跨平台自动化构建系统
  • 从 2021.3 版本起,oneMKL 支持 CMake(详见开发者指南
  • 官网下载并安装最新版本(Latest Release)的 CMake,并勾选添加到系统 PATH 的选项

vcpkg

FFTW

  • FFTW 是一个傅立叶变换库,支持 C、Fortran 等语言
  • oneMKL 提供了无需修改源码的 FFTW 加速接口
  • 成功安装 vcpkg 后,执行 vcpkg install fftw3:x64-windows 命令安装 64 位 Windows 版本的 FFTW 库

构建

  • 打开终端,进入源码目录
    • 执行 mkdir buildcd build 命令,创建并进入 build 目录
    • 执行 cmake -S .. -B . -D CMAKE_GENERATOR_PLATFORM=x64 -DCMAKE_TOOLCHAIN_FILE="{PATH_TO_VCPKG}/scripts/buildsystems/vcpkg.cmake" 命令,生成 64 位项目文件
      • 请将 {PATH_TO_VCPKG} 替换为您的 vcpkg 安装路径
    • 执行 cmake --build . --config Release 命令,使用 Release 配置构建项目

运行测试

  • (在 build 目录)执行 ctest -C Release 命令,将自动依次运行以下四个程序,并输出测试结果
    • random_number_generator,使用 MT19937 算法,生成 2048 * 2048 个在 [0, 1) 区间内均匀分布的伪随机单精度浮点数(种子由源码中 #define SEED 设置),并将结果输出至 rand.txt
    • fftw3_onemkl,读取 rand.txt 作为输入,使用 oneMKL 提供的 FFTW 加速接口,执行 1000 次二维的实数到复数的傅立叶变换(单精度浮点数),将计算结果输出至 result_fftw3_onemkl.txt,并打印平均执行时长
    • fftw3_original,读取 rand.txt 作为输入,使用原版 FFTW 接口,执行 1000 次二维的实数到复数的傅立叶变换(单精度浮点数),将计算结果输出至 result_fftw3_original.txt,并打印平均执行时长
    • compare,读取 fftw3_onemklfftw3_original 输出的结果,并分别计算实部和虚部的平均误差值,当两者平均误差值都小于 0.0001 时测试通过,否则测试失败

测试结果

  • 如下图所示,可打开 build/Testing/Temporary/LastTest.log 查看详细的测试结果

  • 实部和虚部的平均误差值都小于 0.0001,测试通过(有趣的是,我尝试替换了几次随机数种子,最后得到的平均误差值都是 0.000085)

  • oneMKL 提供的 FFTW 加速接口平均执行时间 0.012634 秒,原版 FFTW 接口平均执行时间 0.025977 秒,使用 oneMKL,计算速度高达原版的 205.61%

oneMKL 使用体验

个人感觉 oneMKL 使用起来还是有一定难度(主要在构建配置上),但只要学习安装目录下的样例代码,再多读读官方文档,还是能比较快做一个 DEMO 出来的。

令我非常惊喜的是,使用 oneMKL 提供的 FFTW 加速接口完全不需要改动源码,只需链接 oneMKL,这极大降低了开发者的接口学习负担(本项目也充分利用了这一特性,用一份代码生成两个不同程序)。