2026a

# FFTW 在不同机器上的精度误差


AVX2 是英特尔(Intel)开发的高级矢量扩展指令集,属于 AVX(Advanced Vector Extensions)架构的第二代版本,于 2013 年随第四代酷睿处理器(Haswell 架构)首次推出。它是对早期 SIMD(单指令多数据)指令集(如 SSE、AVX)的扩展和增强,主要用于提升处理器在并行计算、数据处理领域的性能。

机器型号不同,支持的指令集也不同,如 E5-4650 CPU 不支持 AVX2,Gold 6151 CPU 支持 AVX2。对于 FFTW 而言,由于上述机器指令集差异,可能会导致计算结果存在 e-14 ~ e-15 的精度误差。

一般而言,用户无需关心这个精度差异。但是在一些场景下,用户想要 FFTW 在所有机器上计算结果完全一致。这就需要 FFTW 具备切换指令集的能力,从支持 AVX2 指令集切换到去除 AVX2 指令集优化,从而使得计算结果完全保持一致,但是会牺牲 AVX2 带来的性能优化。

# 查看 FFTW 调用的指令集

using FFTW
a=rand(10)
plan_fft(a)
FFTW forward plan for 10-element array of ComplexF64
(dft-direct-10 "n2fv_10_avx2_128")

# FFTW 切换指令集

FFTW 函数库提供了灵活的指令集切换接口,支持切换为 no-avx2default两种指令集,缺省为default指令集,即支持 AVX2 指令集。

using FFTW
using TyRandom
rng = MT19937ar(5489)
a = rand(rng, 10)
fft(a)
10-element Vector{ComplexF64}:
  6.238553055831749 + 0.0im
  1.3775790293294123 + 0.2680564643864721im
  -0.28694024281645475 + 1.096333425951602im
  0.7245808988574451 - 0.5530850838817718im
  -0.5516760566179486 - 0.8956979013637627im
  -0.6184034494048679 + 0.0im
  -0.5516760566179486 + 0.8956979013637627im
  0.7245808988574451 + 0.5530850838817718im
  -0.28694024281645475 - 1.096333425951602im
  1.3775790293294123 - 0.2680564643864721im

可以使用 set_libfftw 切换到no-avx2指令集:

using FFTW
using TyRandom
FFTW.set_libfftw("no-avx2")
rng = MT19937ar(5489)
a = rand(rng, 10) 
fft(a)
10-element Vector{ComplexF64}:
   6.238553055831749 + 0.0im
  1.3775790293294123 + 0.2680564643864721im
 -0.2869402428164547 + 1.096333425951602im
  0.7245808988574451 - 0.5530850838817718im
 -0.5516760566179486 - 0.8956979013637627im
 -0.6184034494048679 + 0.0im
 -0.5516760566179486 + 0.8956979013637627im
  0.7245808988574451 + 0.5530850838817718im
 -0.2869402428164547 - 1.096333425951602im
  1.3775790293294123 - 0.2680564643864721im

# FFTW 不同指令集的性能差异

在 10000*10000 的数据规模下,fft 计算耗时在 4.76 s 左右:

using FFTW
using TyRandom
rng = MT19937ar(5489);
a = rand(rng, 10000,10000);
@time fft(a);
4.768173 seconds (1.49 k allocations: 2.980 GiB, 0.19% gc time, 0.11% compilation time)

切换no-avx2指令集后,fft 计算耗时在 7.82 s 左右,性能下降 64%

using FFTW
using TyRandom
FFTW.set_libfftw("no-avx2")
rng = MT19937ar(5489)
a = rand(rng, 10000,10000);
@time fft(a);
7.825137 seconds (1.49 k allocations: 2.980 GiB, 0.12% gc time, 0.06% compilation time)

提示

需要在 FFTW 相关函数被调用前,调用 FFTW.set_libfftw 函数进行指令集切换操作。

FFTW 切换到no-avx2指令集,性能会下降 60% 左右,一般情况下建议不要切换。