bench/bin_float 设计
设计目标
分别测量二进制栈每一层的开销,所用输入使所有层都必须得到相同结果,这样某一层的变化就会体现为某一个报告百分比的变化。
数学背景
对于一个数据集,令 、 和 分别为区块 中 kernel、core 和 checked 路径的每次调用时间(没有 kernel 路径的情形只报告第二个量)。报告的量为
即某一层相对于其下一层的相对中位数配对开销。估计量、配对方式和 bootstrap 区间的推导见 bench 设计。
设计决策
工作负载
| 用例 | 数据集 | 实现 | 协议 |
|---|---|---|---|
bin-float/add, bin-float/mul, bin-float/div | 53、128、512、2048 位 | kernel/coefficient(BinCoeff)、core/bin-float(BinFloat 运算符)、full/checked(BinFloatResult) | Development |
bin-float/elementary/OP,涵盖 28 个函数(exp、exp2、exp10、expm1、ln、log2、log10、log1p、sqrt、rootn、pow、hypot、sin、cos、tan、sinpi、cospi、tanpi、asin、acos、atan、atan2、sinh、cosh、tanh、asinh、acosh、atanh) | 53、128、512 位精度 | core/bin-float(会中止的方法)、full/checked(BinFloatResult) | Development |
bin-float/autotune/square | 4、8、16、…、1024 个 32 位的 limb | BinCoeff 上的 mul-self(x.mul(x))与 square(x.square()) | RegressionGate |
算术输入是最高位和最低位都置位的固定位模式;精度为各操作数位长之和加 4,div 的被除数为两个模式的乘积,因此每个结果都是精确的,每条路径计算的都是同一个数。初等函数的输入是数据集精度下的 1.25、0.5 和 0.25,各自位于其所用函数的定义域内。平方运算的输入是给定 limb 数的模式;该实验针对每个规模在两种等价算法中选择较快者,并报告交叉点规模。
正确性预言
算术输出与精确的 BinCoeff 结果核对,初等函数输出与 core 结果核对(因此 checked 路径必须与 core 一致),平方输出与 x.square() 核对。与预言不符的输出计为失败,且性能测试断言不存在失败,因此比较永远不会发生在计算不同结果的路径之间。
精确输入
精确结果使各路径的算术工作完全相同:没有哪条路径能靠更早舍入而胜出,测得的差异即表示、上下文处理和检查的开销。
正确性 / 不变式
- 计划测试在普通测试运行中编译每个规格,因此基准不会在无人察觉的情况下失效。
- 性能测试断言
failed_count == 0:每个输出都与其预言一致。 - 种子是固定的(
20260715),因此测量顺序和 bootstrap 重抽样都可复现。
被否决的替代方案
- 每个样本使用随机输入。 这会把输入方差混入计时方差;每个数据集使用固定模式可以隔离代码本身的开销。
- 只做端到端计时。 单个数字无法分辨回归发生在 kernel、core 还是 checked 包装层。
边界
- 仅限 native 目标;不对其他目标作任何结论。
- 没有公共 API;该包为
tools/benchmark.py而存在。 - 测量结果是性能页面的证据,绝不是正确性的证据。