7个版本
0.1.8 | 2019年8月14日 |
---|---|
0.1.7 | 2019年8月13日 |
0.1.6 | 2019年7月21日 |
0.1.4 | 2019年6月22日 |
0.1.2 | 2019年5月30日 |
#321 在 图形API
177 星标 & 5 关注者
100KB
1.5K SLoC
mathbench
mathbench
是一套单元测试和基准测试,用于比较多个不同的Rust线性代数库在常见游戏和图形开发任务中的输出和性能。
mathbench
由 glam
的作者编写,并已被用于比较 glam
与其他针对游戏和图形开发的目标3D数学库的性能,包括
基准测试
所有基准测试均使用 Criterion.rs 执行。基准测试逻辑上分为以下几类
- 返回 self - 尝试测量基准测试每种类型的开销。
- 单个操作 - 测量类型上单个常见操作的性能,例如矩阵求逆、向量归一化或乘以两个矩阵。
- 吞吐量操作 - 测量在数据批次上执行常见操作的性能。这些测量通常处理输入批次的操作,例如使用相同的矩阵变换多个向量。
- 工作负载操作 - 这些操作尝试重现游戏开发中常见的负载,以尝试展示在现实世界任务中的性能。
尽管尽了最大努力,但请对微基准测试结果持保留态度。
操作基准
matrix benches
- 执行常见的矩阵操作,如转置、求逆、行列式和乘法。rotation 3d benches
- 执行常见的3D旋转操作。transform 2d & 3d benches
- 测试特殊用途的2D和3D变换类型。这些类型在一定程度上可以与3x3和4x4矩阵基准进行比较。transformations benches
- 在向量上执行仿射变换 - 根据库选择最佳类型,要么是矩阵类型,要么是变换类型。vector benches
- 执行常见的向量操作。
工作负载基准
euler bench
- 对2D和3D向量的数组执行欧拉积分。
基准测试目前主要关注 f32
类型,因为这是当前 glam
所支持的唯一类型。
crate 差异
不同的库具有不同的特性和不同的实现目标的方式。为了尝试进行性能比较,有时 mathbench
会比较类似的功能,但有时它们并不完全相同。以下是不同库在性能比较方面值得关注的一些差异列表。
矩阵与变换
euclid
库不支持其他库测试中使用的通用正方形矩阵类型。相反,它有2D和3D变换类型,可以变换2D和3D向量和点类型。每个库都有不同的类型来支持变换,但 euclid
是在测试的库中唯一的,因为它没有通用正方形矩阵类型。
Transform2D
被存储为3x2的行主矩阵,可以用于变换2D向量和点。
类似地,Transform3D
用于变换3D向量和点。这表示为4x4矩阵,因此它可以直接与其他库进行比较,但它不支持某些操作,如转置。
在 euclid
中没有2x2矩阵类型。
矩阵求逆
请注意,cgmath
和 nalgebra
的矩阵求逆方法返回一个 Option
,而 glam
和 euclid
则不返回。如果使用 glam
或 euclid
对不可逆矩阵求逆,则结果将是无效的(它将包含 NaNs)。
四元数与旋转器
除了提供旋转器的 ultraviolet
之外,大多数库都提供四元数来执行旋转。
宽基准
所有基准测试都分为“宽”或“标量”。这种划分使我们能够更公平地比较这些不同风格的库。
“标量”基准在标准标量 f32
值上操作,一次对一件数据进行计算(或者在 glam
这样的“水平”SIMD库的情况下,一次对 Vec3
/Vec4
进行计算)。
“宽”基准以“垂直”AoSoA(结构化数组中的数组)方式操作,这是一种编程模型,允许充分利用SIMD操作的优势。然而,它也使得算法设计更加困难,因为标量算法不能直接由“宽”架构使用。由于这种算法上的差异,我们也无法真正 直接 比较标量与宽类型的性能,因为它们 并不完全 做相同的事情(宽类型同时处理多件数据)。
“宽”基准测试仍然包括仅包含标量的库 glam
作为比较。即使这种比较有些类似于苹果和橘子,但在这些情况下,在运行“宽”基准测试变体时,glam
被配置为进行相同的 工作量,生成与“宽”版本相同的输出。其目的是为了提供一个关于与使用标量类型编写相同算法相比,“宽”类型可能的吞吐量优势的概念,但这需要额外小心地编写算法。
要了解更多关于 AoSoA 架构的信息,请参阅 nalgebra
的作者撰写的一篇博客文章这篇博客文章,该文章更深入地探讨了 AoSoA 的工作原理及其潜在优势。还可以查看 ultraviolet
的 README 中的“示例”部分,其中讨论了如何将标量算法移植到宽算法,并提供了来自 mathbench
的欧拉积分和光线-球面相交基准测试的示例。
请注意,nalgebra_f32x4
和 nalgebra_f32x8
基准测试需要 Rust
此外,f32x8
基准测试将需要 AVX2
指令集,要启用该指令集,您需要使用以下命令构建:RUSTFLAGS='-C target-feature=+avx2
。
构建设置
默认使用 profile.bench
设置,这些设置在 cargo 参考文档 中有说明。
一些数学库针对特定的指令集进行了优化,并且可能受益于使用与默认设置不同的设置。通常,游戏团队需要决定他们将针对的最小规格。确定最小规格决定了项目的潜在受众规模。这对任何游戏都是一个重要的决定,而且每个项目都是不同的。由于 mathbench
不想假设任何特定项目可能希望使用的构建设置,因此使用了默认设置。
我鼓励使用与默认设置不同的构建设置的用户自行运行基准测试,并考虑发布他们的结果。
基准测试结果
以下是由 mathbench
生成的基准测试表,比较了 glam
性能与 cgmath
、nalgebra
、euclid
、vek
、pathfinder_geometry
、static-math
和 ultraviolet
在 f32
数据上的性能。
这些基准测试在 Linux 上的 Intel i7-4710HQ CPU 上进行。它们使用 1.56.1 (59eed8a2a 2021-11-01)
Rust 编译器编译。低于(更好)的数字在每个行最小值2.5%范围内突出显示。
测试的库版本如下
cgmath
-0.18.0
euclid
-0.22.6
glam
-0.20.1
nalgebra
-0.29.0
pathfinder_geometry
-0.5.1
static-math
-0.2.3
ultraviolet
-0.8.1
vek
-0.15.3
(repr_c
类型)
查看完整的mathbench 报告,获取更详细的结果。
标量基准测试
使用以下命令运行
cargo bench --features scalar scalar
benchmark | glam | cgmath | nalgebra | euclid | vek | pathfinder | static-math | ultraviolet |
---|---|---|---|---|---|---|---|---|
euler 2d x10000 | 16.23 us | 16.13 us | 9.954 us | 16.18 us | 16.2 us | 10.42 us | 9.97 us | 16.17 us |
euler 3d x10000 | 15.95 us | 32.11 us | 32.13 us | 32.13 us | 32.13 us | 16.27 us | 32.16 us | 32.11 us |
matrix2 矩阵行列式 | 2.0386 ns | 2.0999 ns | 2.1018 ns | N/A | 2.0997 ns | 2.0987 ns | 2.0962 ns | 2.1080 ns |
matrix2 矩阵逆 | 2.8226 ns | 8.4418 ns | 7.6303 ns | N/A | N/A | 3.3459 ns | 9.4636 ns | 5.8796 ns |
matrix2 矩阵乘矩阵 | 2.6036 ns | 5.0007 ns | 4.8172 ns | N/A | 9.3814 ns | 2.5516 ns | 4.7274 ns | 4.9428 ns |
matrix2 矩阵乘向量2 x1 | 2.4904 ns | 2.6144 ns | 2.8714 ns | N/A | 4.2139 ns | 2.0839 ns | 2.8873 ns | 2.6250 ns |
matrix2 矩阵乘向量2 x100 | 227.5271 ns | 243.3579 ns | 265.1698 ns | N/A | 400.6940 ns | 219.7127 ns | 267.8780 ns | 243.9880 ns |
matrix2 返回自身 | 2.4235 ns | 2.8841 ns | 2.8756 ns | N/A | 2.8754 ns | 2.4147 ns | 2.8717 ns | 2.8697 ns |
matrix2 转置 | 2.2887 ns | 3.0645 ns | 7.9154 ns | N/A | 2.9635 ns | N/A | 3.0637 ns | 3.0652 ns |
matrix3 矩阵行列式 | 3.9129 ns | 3.8107 ns | 3.8191 ns | N/A | 3.8180 ns | N/A | 3.8151 ns | 8.9368 ns |
matrix3 矩阵逆 | 17.5373 ns | 18.6931 ns | 12.3183 ns | N/A | N/A | N/A | 12.8195 ns | 21.9098 ns |
matrix3 矩阵乘矩阵 | 9.9578 ns | 13.3648 ns | 7.8154 ns | N/A | 35.5802 ns | N/A | 6.4938 ns | 10.0527 ns |
matrix3 矩阵乘向量3 x1 | 4.8090 ns | 4.9339 ns | 4.5046 ns | N/A | 12.5518 ns | N/A | 4.8002 ns | 4.8118 ns |
matrix3 矩阵乘向量3 x100 | 0.4836 us | 0.4808 us | 0.4755 us | N/A | 1.247 us | N/A | 0.4816 us | 0.4755 us |
matrix3 返回自身 | 5.4421 ns | 5.4469 ns | 5.4526 ns | N/A | 5.4656 ns | N/A | 5.4718 ns | 5.4043 ns |
matrix3 转置 | 9.9567 ns | 10.0794 ns | 10.9704 ns | N/A | 9.9257 ns | N/A | 10.7350 ns | 10.5334 ns |
matrix4 矩阵行列式 | 6.2050 ns | 11.1041 ns | 69.2549 ns | 17.1809 ns | 18.5233 纳秒 | N/A | 16.5331 纳秒 | 8.2704 纳秒 |
matrix4 逆矩阵 | 16.4386 纳秒 | 47.0674 纳秒 | 71.8174 纳秒 | 64.1356 纳秒 | 284.3703 纳秒 | N/A | 52.6993 纳秒 | 41.1780 纳秒 |
matrix4 乘 matrix4 | 7.7715 纳秒 | 26.7308 纳秒 | 8.6500 纳秒 | 10.4414 纳秒 | 86.1501 纳秒 | N/A | 21.7985 纳秒 | 26.8056 纳秒 |
matrix4 乘 vector4 x1 | 3.0303 纳秒 | 7.7400 纳秒 | 3.4091 纳秒 | N/A | 21.0968 纳秒 | N/A | 6.2971 纳秒 | 6.2537 纳秒 |
matrix4 乘 vector4 x100 | 0.6136 微秒 | 0.9676 微秒 | 0.627 微秒 | N/A | 2.167 微秒 | N/A | 0.7893 微秒 | 0.8013 微秒 |
matrix4 返回自身 | 7.1741 纳秒 | 6.8838 纳秒 | 7.5030 纳秒 | N/A | 7.0410 纳秒 | N/A | 6.7768 纳秒 | 6.9508 纳秒 |
matrix4 转置 | 6.6826 纳秒 | 12.4966 纳秒 | 15.3265 纳秒 | N/A | 12.6386 纳秒 | N/A | 15.2657 纳秒 | 12.3396 纳秒 |
ray-sphere intersection x10000 | 56.2 微秒 | 55.7 微秒 | 15.32 微秒 | 55.45 微秒 | 56.02 微秒 | N/A | N/A | 50.94 微秒 |
rotation3 逆矩阵 | 2.3113 纳秒 | 3.1752 纳秒 | 3.3292 纳秒 | 3.3311 纳秒 | 3.1808 纳秒 | N/A | 8.7109 纳秒 | 3.6535 纳秒 |
rotation3 乘 rotation3 | 3.6584 纳秒 | 7.5255 纳秒 | 7.4808 纳秒 | 8.1393 纳秒 | 14.1636 纳秒 | N/A | 6.8044 纳秒 | 7.6386 纳秒 |
rotation3 乘 vector3 x1 | 6.4950 纳秒 | 7.6808 纳秒 | 7.5784 纳秒 | 7.5746 纳秒 | 18.2547 纳秒 | N/A | 7.2727 纳秒 | 8.9732 纳秒 |
rotation3 乘 vector3 x100 | 0.6465 微秒 | 0.7844 微秒 | 0.7573 微秒 | 0.7533 微秒 | 1.769 微秒 | N/A | 0.7317 微秒 | 0.9416 微秒 |
rotation3 返回自身 | 2.4928 纳秒 | 2.8740 纳秒 | 2.8687 纳秒 | N/A | 2.8724 纳秒 | N/A | 4.7868 纳秒 | 2.8722 纳秒 |
transform point2 x1 | 2.7854 纳秒 | 2.8878 纳秒 | 4.4207 纳秒 | 2.8667 纳秒 | 11.9427 纳秒 | 2.3601 纳秒 | N/A | 4.1770 纳秒 |
transform point2 x100 | 0.3316 微秒 | 0.3574 微秒 | 0.4445 微秒 | 0.3008 微秒 | 1.212 微秒 | 0.3184 微秒 | N/A | 0.4332 微秒 |
transform point3 x1 | 2.9619 纳秒 | 10.6812 纳秒 | 6.1037 纳秒 | 7.7051 纳秒 | 13.2607 纳秒 | 3.0934 纳秒 | N/A | 6.8419 纳秒 |
transform point3 x100 | 0.6095 微秒 | 1.27 微秒 | 0.8064 微秒 | 0.7674 微秒 | 1.446 微秒 | 0.6189 微秒 | N/A | 0.8899 微秒 |
transform vector2 x1 | 2.4944 纳秒 | N/A | 3.7174 纳秒 | 2.6273 纳秒 | 11.9424 纳秒 | N/A | N/A | 3.0458 纳秒 |
transform vector2 x100 | 0.3125 微秒 | N/A | 0.3871 微秒 | 0.2817 微秒 | 1.213 微秒 | N/A | N/A | 0.3649 微秒 |
transform vector3 x1 | 2.8091 纳秒 | 7.7343 纳秒 | 5.5064 纳秒 | 4.4810 纳秒 | 15.4097 纳秒 | N/A | N/A | 4.8819 纳秒 |
transform vector3 x100 | 0.6035 微秒 | 0.9439 微秒 | 0.7573 微秒 | 0.6327 微秒 | 1.63 微秒 | N/A | N/A | 0.6703 微秒 |
transform2 逆矩阵 | 9.0256 纳秒 | N/A | 12.2614 纳秒 | 9.4803 纳秒 | N/A | 8.9047 纳秒 | N/A | N/A |
transform2 乘 transform2 | 4.5111 纳秒 | N/A | 8.1434 纳秒 | 5.8677 纳秒 | N/A | 3.8513 纳秒 | N/A | N/A |
transform2 返回自身 | 4.1707 纳秒 | N/A | 5.4356 纳秒 | 4.2775 纳秒 | N/A | 4.1117 纳秒 | N/A | N/A |
transform3 逆矩阵 | 10.9869 纳秒 | N/A | 71.4437 纳秒 | 56.0136 纳秒 | N/A | 23.0392 纳秒 | N/A | N/A |
transform3 乘 transform3d | 6.5903 纳秒 | N/A | 8.5673 纳秒 | 10.1802 纳秒 | N/A | 7.6587 纳秒 | N/A | N/A |
transform3 返回自身 | 7.1828 纳秒 | N/A | 7.2619 纳秒 | 7.2407 纳秒 | N/A | 7.3214 纳秒 | N/A | N/A |
vector3 叉乘 | 2.4257 纳秒 | 3.6842 纳秒 | 3.7945 纳秒 | 3.6821 纳秒 | 3.8323 纳秒 | N/A | 3.8622 纳秒 | 3.6927 纳秒 |
vector3 点乘 | 2.1055 纳秒 | 2.3179 纳秒 | 2.3174 纳秒 | 2.3190 纳秒 | 2.3195 纳秒 | N/A | 2.3204 纳秒 | 2.3160 纳秒 |
vector3 长度 | 2.5020 纳秒 | 2.5002 纳秒 | 2.5986 纳秒 | 2.5013 纳秒 | 2.5021 纳秒 | N/A | 2.5036 纳秒 | 2.5017 纳秒 |
vector3 归一化 | 4.0454 纳秒 | 5.8411 纳秒 | 8.4069 纳秒 | 8.0679 纳秒 | 8.8137 纳秒 | N/A | N/A | 5.8440 纳秒 |
vector3 返回自身 | 2.4087 纳秒 | 3.1021 纳秒 | 3.1061 纳秒 | N/A | 3.1052 纳秒 | N/A | 3.1136 纳秒 | 3.1071 纳秒 |
宽基准
这些基准测试在 Linux 系统上的 Intel i7-4710HQ CPU 上进行。它们使用 Rust 编译器编译,版本为 1.59.0-nightly (207c80f10 2021-11-30)
。每行的最小值2.5%范围内的更低(更好)的数字被突出显示。
测试的库版本如下
glam
-0.20.1
nalgebra
-0.29.0
ultraviolet
-0.8.1
使用以下命令运行
RUSTFLAGS='-C target-feature=+avx2' cargo +nightly bench --features wide wide
benchmark | glam_f32x1 | ultraviolet_f32x4 | nalgebra_f32x4 | ultraviolet_f32x8 | nalgebra_f32x8 |
---|---|---|---|---|---|
euler 2d x80000 | 142.7 微秒 | 63.47 微秒 | 63.94 微秒 | 69.27 微秒 | 69.25 微秒 |
euler 3d x80000 | 141.2 微秒 | 97.18 微秒 | 95.78 微秒 | 103.7 微秒 | 105.7 微秒 |
matrix2 矩阵行列式 x16 | 18.6849 纳秒 | 11.4259 纳秒 | N/A | 9.9982 纳秒 | N/A |
matrix2 逆矩阵 x16 | 39.1219 纳秒 | 29.8933 纳秒 | N/A | 22.8757 纳秒 | N/A |
matrix2 矩阵乘矩阵 x16 | 42.7342 纳秒 | 36.4879 纳秒 | N/A | 33.4814 纳秒 | N/A |
matrix2 矩阵乘矩阵 x256 | 959.1663 纳秒 | 935.4148 纳秒 | N/A | 862.0910 纳秒 | N/A |
matrix2 矩阵乘向量 x16 | 41.2464 纳秒 | 18.2382 纳秒 | N/A | 17.2550 纳秒 | N/A |
matrix2 矩阵乘向量 x256 | 698.1177 纳秒 | 544.5315 纳秒 | N/A | 540.9743 纳秒 | N/A |
matrix2 返回自身 x16 | 32.7553 纳秒 | 29.5064 纳秒 | N/A | 21.4492 纳秒 | N/A |
matrix2 转置 x16 | 32.3247 纳秒 | 46.4836 纳秒 | N/A | 20.0852 纳秒 | N/A |
matrix3 矩阵行列式 x16 | 53.2366 纳秒 | 25.0158 纳秒 | N/A | 22.1503 纳秒 | N/A |
matrix3 逆矩阵 x16 | 275.9330 纳秒 | 78.3532 纳秒 | N/A | 69.2627 纳秒 | N/A |
matrix3 矩阵乘矩阵 x16 | 239.6124 纳秒 | 115.2934 纳秒 | N/A | 116.6237 纳秒 | N/A |
matrix3 矩阵乘矩阵 x256 | 3.26 微秒 | 1.959 微秒 | N/A | 1.963 微秒 | N/A |
matrix3 矩阵乘向量 x16 | 78.4972 纳秒 | 40.4734 纳秒 | N/A | 47.0164 纳秒 | N/A |
matrix3 矩阵乘向量 x256 | 1.293 微秒 | 1.0 微秒 | N/A | 1.007 微秒 | N/A |
matrix3 返回自身 x16 | 112.4312 纳秒 | 78.4870 纳秒 | N/A | 67.3272 纳秒 | N/A |
matrix3 转置 x16 | 116.9654 纳秒 | 100.1097 纳秒 | N/A | 67.4544 纳秒 | N/A |
matrix4 矩阵行列式 x16 | 98.8388 纳秒 | 56.1177 纳秒 | N/A | 55.7623 纳秒 | N/A |
matrix4 逆矩阵 x16 | 276.2637 纳秒 | 191.7471 纳秒 | N/A | 163.8408 纳秒 | N/A |
matrix4 矩阵乘矩阵 x16 | 230.9916 纳秒 | 222.3948 纳秒 | N/A | 221.8563 纳秒 | N/A |
matrix4 矩阵乘矩阵 x256 | 3.793 微秒 | 3.545 微秒 | N/A | 3.67 微秒 | N/A |
matrix4 矩阵乘向量 x16 | 92.9485 纳秒 | 87.7341 纳秒 | N/A | 90.4404 纳秒 | N/A |
matrix4 矩阵乘向量 x256 | 1.58 微秒 | 1.542 微秒 | N/A | 1.596 微秒 | N/A |
matrix4 返回自身 x16 | 175.6153 纳秒 | 158.7861 纳秒 | N/A | 167.6639 纳秒 | N/A |
matrix4 转置 x16 | 184.0498 纳秒 | 193.5497 纳秒 | N/A | 147.1365 纳秒 | N/A |
ray-sphere intersection x80000 | 567.9 微秒 | 154.8 微秒 | N/A | 61.49 微秒 | N/A |
rotation3 逆矩阵 x16 | 32.7517 纳秒 | 32.8107 纳秒 | N/A | 22.3662 纳秒 | N/A |
rotation3 乘 rotation3 x16 | 58.9408 纳秒 | 38.6848 纳秒 | N/A | 34.3223 纳秒 | N/A |
rotation3 乘 vector3 x16 | 130.6707 纳秒 | 36.7861 纳秒 | N/A | 26.1154 纳秒 | N/A |
rotation3 返回 self x16 | 32.4345 纳秒 | 32.5213 纳秒 | N/A | 21.8325 纳秒 | N/A |
transform point2 x16 | 52.6534 纳秒 | 31.4527 纳秒 | N/A | 32.7317 纳秒 | N/A |
transform point2 x256 | 888.5654 纳秒 | 831.9341 纳秒 | N/A | 848.0397 纳秒 | N/A |
transform point3 x16 | 96.9017 纳秒 | 81.6828 纳秒 | N/A | 82.8904 纳秒 | N/A |
transform point3 x256 | 1.567 微秒 | 1.398 微秒 | N/A | 1.43 微秒 | N/A |
transform vector2 x16 | 43.7679 纳秒 | 29.9349 纳秒 | N/A | 31.8630 纳秒 | N/A |
transform vector2 x256 | 858.5660 纳秒 | 825.0261 纳秒 | N/A | 851.7501 纳秒 | N/A |
transform vector3 x16 | 96.5535 纳秒 | 80.1612 纳秒 | N/A | 85.0659 纳秒 | N/A |
transform vector3 x256 | 1.557 微秒 | 1.394 微秒 | N/A | 1.438 微秒 | N/A |
vector3 cross x16 | 42.1941 纳秒 | 26.6677 纳秒 | N/A | 22.0924 纳秒 | N/A |
vector3 dot x16 | 29.1805 纳秒 | 12.7972 纳秒 | N/A | 12.2872 纳秒 | N/A |
vector3 length x16 | 32.6014 纳秒 | 9.7692 纳秒 | N/A | 9.4271 纳秒 | N/A |
vector3 normalize x16 | 65.8815 纳秒 | 24.1661 纳秒 | N/A | 20.3579 纳秒 | N/A |
vector3 return self x16 | 32.0051 纳秒 | 42.9462 纳秒 | N/A | 16.7808 纳秒 | N/A |
运行基准测试
基准测试使用 criterion crate,该 crate 在稳定版 Rust 中运行,可以使用以下命令运行:
cargo bench
为了获得最佳结果,请在基准测试机器上关闭其他应用程序!
运行“宽”基准测试时,请确保已启用适当的 target-feature
,例如 +avx2
,以获得最佳结果。
在 scripts/summary.py
中有一个脚本,可以以美观的方式总结结果。它需要 Python 3 和 prettytable
Python 模块,然后可以运行以生成 ASCII 输出。
默认和可选功能
除了 glam
之外,所有库都是运行基准测试的可选功能。默认功能包括 cgmath
、ultraviolet
和 nalgebra
。这些可以通过以下方式禁用:
cargo bench --no-default-features
要再次选择性地启用特定的默认功能,请使用
cargo bench --no-default-features --features nalgebra
请注意,您可以使用 Criterion 的过滤功能在运行时选择要运行的基准测试。例如,要仅运行标量基准测试而不运行宽基准测试,请使用
cargo bench "scalar"
您还可以更详细地选择。例如,要仅运行宽矩阵2基准测试,请使用
cargo bench --features wide "wide matrix2"
或要仅运行 glam
的标量 "vec3 length" 基准测试,请使用
cargo bench "scalar vec3 length/glam"
Crates 功能
除了直接引用每个基准测试库的功能之外,还有一些额外的功能。
ultraviolet_f32x4
、ultraviolet_f32x8
、nalgebra_f32x4
、nalgebra_f32x8
- 这些各自启用从ultraviolet
或nalgebra
中特定宽类型的基准测试。ultraviolet_wide
、nalgebra_wide
- 这些分别启用从ultraviolet
或nalgebra
中所有宽类型的基准测试。wide
- 启用所有“宽”类型基准测试all
- 启用所有受支持的库,包括宽和标量库。unstable
- 参见下一节
unstable
功能
不稳定的特性需要使用夜间编译器,并允许我们告诉rustc不要在热基准循环内内联某些函数。这在ray-sphere intersection基准测试中用于模拟自动向量化器无法正确向量化你的代码的情况。
运行测试
可以使用以下方式运行测试:
cargo test
发布结果
在发布基准测试结果时,记录基准测试的详细信息非常重要,包括:
- 使用的
mathbench
版本 - 所有基准测试库的版本
- Rust版本
- 使用的构建设置,特别是当它们与默认设置不同时
- 使用的硬件规格
scripts/summary.py
的输出target/criterion
的完整 Criterion 输出
添加新的库
为新的库添加单元测试和基准测试涉及不同的步骤。
基准测试需要一个实现mathbench::RandomVec
特质的实现,用于你想要基准测试的类型。如果类型实现了rand
crate的distribution::Distribution
特质用于Standard
,则可以直接在src/lib.rs
中使用impl_random_vec!
宏。否则,你可以提供一个生成新随机值的函数,将其传递给impl_random_vec!
。
要将新库类型添加到基准测试中,将另一个bench_function
调用添加到Criterion
的BenchmarkGroup
。
在Cargo.toml
中增加mathbench
的补丁版本号。
更新CHANGELOG.md
。
构建时间
mathbench
还包括一个工具,可以在tools/buildbench
中比较完整构建时间。增量构建时间没有测量,因为创建一个有意义的不同数学crate的测试将是非平凡的。
buildbench
工具使用cargo
夜间构建的-Z
计时功能,因此你需要一个夜间构建才能运行它。
buildbench
在每个库中生成一个临时的Cargo.toml
和空的src/lib.rs
,记录一些构建时间信息,这些信息包含在下表的摘要表中。临时目录在每次运行工具时都会创建,因此这是一个从干净状态开始的完整构建。
每个库只构建一次,因此你可能需要多次运行buildbench
以确保结果一致。
默认情况下,crate使用带有默认功能的release
配置文件构建。还有构建dev
配置文件或不带默认功能的选项,请参阅buildbench --help
获取更多信息。
输出的列包括总构建时间、自构建时间(不包括依赖项构建时间的构建时间),以及单元数量(这至少是2)。
在比较构建时间时,请注意每个库都有不同的功能集,并且自然较大的库构建时间会更长。对于许多测试的crate,依赖项的构建时间比数学crate更长。还要注意,如果你已经在项目中构建了一个依赖项,你不需要支付两次构建成本(除非它是不同版本)。
crate | 版本 | 总时间(秒) | 自构建时间(秒) | 单元数量 |
---|---|---|---|---|
cgmath | 0.17.0 | 6.8 | 3.0 | 17 |
euclid | 0.22.1 | 3.4 | 1.0 | 4 |
glam | 0.9.4 | 1.1 | 0.6 | 2 |
nalgebra | 0.22.0 | 24.2 | 18.0 | 24 |
pathfinder_geometry | 0.5.1 | 3.0 | 0.3 | 8 |
static-math | 0.1.6 | 6.9 | 1.7 | 10 |
ultraviolet | 0.5.1 | 2.5 | 1.3 | 4 |
vek | 0.12.0 | 34.4 | 10.1 | 16 |
这些基准测试是在一个搭载16GB RAM和东芝MQ01ABD100硬盘(SATA 3Gbps 5400RPM)的英特尔i7-4710HQ CPU上在Linux系统上进行的。
许可证
根据以下任一许可证授权:
- Apache许可证,版本2.0(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT许可证(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
由您选择。
贡献
对本项目的任何形式(问题、拉取请求等)的贡献必须遵守Rust的行为准则。
除非您明确声明,否则任何提交以包含在作品中的贡献(根据Apache-2.0许可证定义),将根据上述许可证双授权,不附加任何额外条款或条件。
支持
如果您有兴趣贡献或有请求或建议,请在github上创建问题。
依赖关系
~8.5MB
~201K SLoC