5 个版本
0.2.3 | 2024年7月22日 |
---|---|
0.2.2 | 2024年6月6日 |
0.2.1 | 2024年6月6日 |
0.2.0 | 2024年6月6日 |
0.1.0 | 2024年6月6日 |
在 编程语言 中排名第 139
每月下载量 131
320KB
942 行
分阶段滤波器
-
一个快速萨维茨基-戈拉滤波器。
-
所有 (N,M) 参数都在编译时预先计算并加载。
-
通过
rayon
功能标志提供rayon
支持 -
还有一些 SIMD 性能待提高 - 新版本将专注于性能
-
请记住使用以下命令编译此程序以获得最佳性能:
RUSTFLAGS="-C target-cpu=native"
.
此代码基于我在 Julia 中修改的另一个代码,得到了许多人的帮助,请参阅 StagedFilters.jl.
示例
基准测试
其他 savgol-rs
实现提供此速度
use savgol_rs::*;
fn main() {
let input = SavGolInput {
data: &vec![10.0; 500_000],
window_length: 3,
poly_order: 1,
derivative: 0,
};
let result = savgol_filter(&input);
let data = result.unwrap();
println!("{:?}", &data[0..10]);
}
大约需要 52s
,而此包
use staged_sg_filter::sav_gol;
fn main() {
let n = 100_000_000;
let v = vec![10.0; n];
let mut buf = vec![0.0; n];
sav_gol::<1, 1>(&mut buf, &v);
println!("{:?}", &buf[0..10]);
}
在 20 倍数据大小的情况下运行时间约为 200ms
。我们大约每秒处理约 100_000_000/0.2 ≈ 5e8
个元素或 5e8 * 10^-9 ≈ 0.5
个元素每纳秒。
这还可以通过约 4 倍的因子进行改进,这是 Julia 代码的当前速度。
注意
之所以称为“分阶段”,是因为计算是在“阶段”中进行的,这使得编译器能够大量优化代码 - 也就是说,Rust 中的 const 泛型提供了更多循环展开和正确 SIMD 通道宽度的机会。
您需要具有 FMA 和 AVX2 兼容的硬件(至少)。请使用以下命令编译以获得最佳性能:RUSTFLAGS="-C target-cpu=native" cargo run --release
。
已经做出了相当大的努力来确保
- 最小化依赖关系和快速构建
- 自动向量化通过
cargo-remark
实现 - 使用预计算系数和
const
泛型将尽可能多的计算推到编译时 - 热路径是分配和无恐慌的
算法
- 在 Julia 中计算感兴趣的系数,将它们复制/粘贴到
coeffs/_f32.rs
中适当的位置,并声明为const
。 - 使用之前获得的
coeffs
作为一半元素大小进行固定大小的滚动窗口 dot_product。 - 更新
buf
fer 的每个元素 - 使用 Rayon 并行化
待办事项
- rayon 支持
- 仅计算 12x12 以内的 NxM 并将其缓存
- 支持 fma
- 支持 f32/f64 浮点数
- 支持 SIMD
- 支持 GPU / ping Manuel Drehwald
-
no_std
支持 see(Effective Rust 链接) - 支持导数(目标 - 赞助我?)
依赖项
~0–265KB