#fft #benchmark #wav #bench #processing #build #measure

app fft_bench

使用FFT进行基准测试

2个版本

0.1.1 2020年7月14日
0.1.0 2020年7月14日

#440 in 命令行界面

MIT/Apache

28KB
456

fft_bench

在开发运行在RPi3上的产品时,我想得到RPi3的性能指标。

我还发现,Rust的调试版本和发布版本在处理速度上存在很大差异。

因此,我编写了一个简单的程序并得到了基准测试。

您可以使用以下命令步骤运行基准测试。

$ git clone https://github.com/zuntan/fft_bench.git
$ cd fft_bench
$ cargo check
$ ( TIME="\nTIME R:%e S:%S U:%U P:%P CMD:%C"; \time bash run_bench.sh 2>&1 ) | tee result/result.txt

( 我不会说英语,所以我用谷歌翻译来写文本。请原谅我奇怪的句子。 )

关于这个基准测试程序

该程序内部生成正弦波,并使用FFT分析数据。

然后,通过测量程序的编译时间和处理时间来获取基准测试。

该程序有以下选项。

$ cargo run -- --help
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/fft_bench --help`
Usage: target/debug/fft_bench [options]

Options:
    -w, --wav [tmp.wav] wav file output
    -x, --fftbw_wav [tmp_fftbw.wav]
                        wav file output (fft backword)
    -l, --len 15        wav file output len (sec)
    -f, --freq 1000     frequency (20-20000)
    -6, --f64           use f64 insteed of f32
    -s, --skip_fft      skip fft
    -b, --enable_fft_backward
                        enable fft_backward
    -v, --version       Print version info and exit.
        --help          Print this help menu.
  • -l

    • 生成波形数据的时间。单位是秒。
  • -f

    • 生成的正弦波频率。可以指定多个。默认是A和弦。
  • -6

    • FFT处理类型是f64。默认是f32。
  • -w

    • 使用指定的文件名输出生成的数据。
  • -s

    • 跳过FFT处理。
  • -b

    • 执行逆FFT处理。
  • -x

    • 将逆FFT处理的结果保存到指定的文件名。如果指定了-s则无效。如果没有指定-b则无效。
  • 示例

$ cargo run  --release -- -l 180 -6 -w -b -x  ***
    Finished release [optimized] target(s) in 0.01s
     Running `target/release/fft_bench -l 180 -6 -w -b -x`
 INFO  fft_bench > f64           [true]
 INFO  fft_bench > skip_fft      [false]
 INFO  fft_bench > wav output    [tmp.wav]
 INFO  fft_bench > enable_fft_bw [true]
 INFO  fft_bench > wav output bw [tmp_fftbw.wav]
 INFO  fft_bench > wav len       [180] sec
 INFO  fft_bench > freqs         [440.0, 554.364990234375, 659.2550048828125]
 INFO  fft_bench > wav amp     [3.0]
 INFO  fft_bench > 30 sec done
 INFO  fft_bench > 60 sec done
 INFO  fft_bench > 90 sec done
 INFO  fft_bench > 120 sec done
 INFO  fft_bench > 150 sec done
 INFO  fft_bench > 180 sec done
 INFO  fft_bench > fft count       [1939]
 INFO  fft_bench > wav sample len  [7938048]
 INFO  fft_bench > wav file   len  [15884332]
 INFO  fft_bench > wav time    (1) [ 180.0011] sec
 INFO  fft_bench > proc time   (2) [   0.7240] sec
 INFO  fft_bench > (1) / (2)       [ 248.6203]
  • 谢谢
    • Hound Rust中的wav编码和解码库。
    • chfft 使用纯Rust实现的快速傅里叶变换库。
    • 许多其他库作者

关于这个基准测试shell脚本(run_bench.sh)

它测量了该项目的编译时间和程序执行。

在前半部分,测量cargo(rust)的处理速度

后半部分测量该程序的执行时间。FFT处理中f32和f64之间的差异以及DEBUG构建和RELEASE构建之间的差异很有趣。

  1. 运行 "cargo clean"。 - 首先,清理它。
  2. 运行 "cargo check"。 - 测量 "cargo check" 的处理时间。 - 如果有任何下载,请再次尝试。
  3. 触摸main.rs后,再次运行 "cargo check"。 - 仅测量main.rs的处理时间。
  4. 运行 "cargo build"。 - 测量 "cargo build" 的处理时间。
  5. 触摸main.rs后,再次运行 "cargo build"。 - 仅测量main.rs的处理时间。
  6. 运行 "cargo build --release"。 - 测量 "cargo build --release" 的处理时间。
  7. 修改 main.rs 后,再次运行 "cargo build --release"。 - 仅测量 main.rs 的处理时间。
  8. 使用各种参数运行 "fft_benchi"。
    • -s ... 跳过 FFT 无输出
    • -s -w ... 跳过 FFT 仅波形输出
    • ... 启用 FFT 无输出
    • -b ... 启用 FFT 启用 FFT 逆序 无输出
    • -w ... 启用 FFT 波形输出
    • -b -x ... 启用 FFT 启用 FFT 逆序 波形输出 波形 FFT 逆序输出
    • -6 ... f64 启用 FFT 无输出
    • -6 -b ... f64 启用 FFT 启用 FFT 逆序 无输出
    • -6 -w ... f64 启用 FFT 波形输出
    • -6 -w -b -x ... f64 启用 FFT 启用 FFT 逆序 波形输出 波形 FFT 逆序输出
  9. 运行 cat /proc/cpuinfo
  10. 运行 free -hcat /proc/meminfo

运行此基准测试将在当前目录中产生 tmp.wav 和 tmp_fftbw.wav。

tmp.wav 是一个文件,其中 A、C# 和 E 的和弦持续 180 秒。

tmp_fftbw.wav 是在 FFT 处理 tmp.wav 数据之后执行逆 FFT 处理获得的数据。

请尝试聆听。

测量结果摘要

在我的服务器和 Raspberry Pi 3 上运行的结果在结果目录中

编译速度比较

X86 X86(CPU) RPi 3B RPi 3B(CPU) RPi 3B : X86
cargo check 1 3.66 355% 48.48 303% 13.25
cargo check 2 0.07 101% 0.61 102% 8.71
cargo build 1 6.15 488% 97.84 343% 15.91
cargo build 2 0.92 102% 12.91 100% 14.03
cargo build --release 1 9.65 824% 177.4 285% 18.38
cargo build --release 2 1.38 413% 18.76 278% 13.59
cargo build 1 (cross arm7) 6.61 458% 96.10 345% 14.54
cargo build 2 (cross arm7) 1.36 101% 12.91 100% 9.49
cargo build --release 1 (cross arm7) 9.35 845% 176.36 383% 18.86
cargo build --release 2 (cross arm7) 1.47 389% 18.08 278% 12.30
  • 在编译时,X86 方面比 RPi 3B 快 8 到 14 倍。干净构建时快 13-18 倍

  • 调试构建和发布构建之间的差异大约是 1.5 倍,这不是一个很大的差异。

  • 根据我的经验,在 RPi 3B 上编译大型项目可能需要 10 分钟或更长时间,因此重复在 RPi 3B 上构建效率不高。可以说,在交叉编译环境中开发是高效的。

程序速度比较

FFT FFT-BW FILE-OUT f64 X86 (D) RPi 3B (D) X86 (R) RPi 3B (R) X86(D)/(R) RPi 3B (D)/(R) RPi 3B(D) : X86(D) RPi 3B(R) : X86(R)
-s 4.44 31.38 0.29 3.45 15.31 9.10 7.07 9.10
-s-w * 4.02 21.77 0.31 3.58 12.97 6.08 5.42 6.08
* 8.33 35.60 0.37 4.38 22.51 8.13 4.27 8.13
-b * * 13.98 57.38 0.45 5.28 31.07 10.87 4.10 10.87
-w * * 8.80 38.24 0.38 4.56 23.16 8.39 4.35 8.39
-b-x * * * 15.18 65.47 0.49 6.25 30.98 10.48 4.31 10.48
-6 * * 6.52 37.12 0.59 5.85 11.05 6.35 5.69 6.35
-6 -b * * * 10.24 59.81 0.70 7.12 14.63 8.40 5.84 8.40
-6 -w * * * 7.00 41.56 0.61 6.05 11.48 6.87 5.94 6.87
-6 -w-b-x * * * * 11.26 68.17 0.74 8.52 15.22 8.00 6.05 8.00
  • 调试构建和发布构建之间的执行速度差异非常大。[ X86(D)/(R), RPi 3B (D)/(R) ]

    • RPi3B 有 6 到 10 倍,X86 有 15 到 31 倍!
  • *** 无论如何,调试构建运行得太慢了。 ***

  • RPi3B与X86之间的执行速度差异为6到10倍。[RPi 3B(R) : X86(R)]

    • 使用此方法,似乎文件输出与否没有显著差异。
    • 在RPi3B上,f32似乎比f64快。可能是因为操作系统是32位的。
    • 在x86上,f64似乎比f32快。可能是因为操作系统是64位的。然而,在发布版本中,f32和f64之间的差异不大。

总时间

  • X86服务器
    • 135.55秒 | 02:15.55 ( 251% CPU )
  • RPi 3B
    • 1173.49秒 | 19:33.49 ( 239% CPU )
  • RPi 3B / X86服务器
    • 8.657 ( 865.7 % )

一般评论

  • 根据程度,与其在RPi3B上使用Rust,不如在一定程度上在X86机器上开发,然后在RPi3B上运行交叉构建的版本。

    • 否则,你将在编译时花费很多时间休息和喝咖啡。我快要崩溃了。
  • 那时,考虑到性能差异约为10倍,用RPi3B开发是个好主意。

  • 如果你使用RPi3B,***请务必使用发布版本。***调试版本运行得太慢。

    • 我差点因为处理速度严重不足而放弃开发。

依赖项

~4–13MB
~132K SLoC