go 建议:x/perf/cmd/benchrun:添加-run和-count选项

rkue9o1l  于 5个月前  发布在  Go
关注(0)|答案(6)|浏览(46)

使用benchstat收集高质量基准测试有点烦人。首先,你必须多次运行它们,理想情况下,你希望交错旧的和新的二进制文件,使噪音相关性更小。
添加 -run 布尔选项,如果设置了该选项,则旧的、新的 ... 文件路径不是 go test 的输出,而是 go test -cbenchstat 将使用Thue-Morse序列调用这些文件,并使用 benchstat 的 -test.run=$^-test.bench= 选项值以及 -filter 选项值。
-count 指定每个应该发生多少次调用,每次调用都将使用 -test.count=1(或未设置)。
预期用法:

> go test -c -o /tmp/new
> git checkout HEAD~1
> go test -c -o /tmp/old
> benchstat -run -count=10 /tmp/{old,new}
628mspwn

628mspwn1#

要获取二进制文件,需要检出特定的修订版本并进行编译。我编写了以下 benchrev.sh 脚本:

#!/bin/bash
set -euo pipefail

if [ "$#" -lt 6 ]; then
    echo "Usage: $0 <revision A> <revision B> [<go test -bench=...>]"
    echo "Runs benchmark for each revision and prints benchstat results."
    echo "Example:"
    echo "  $0 master HEAD ../bin/go test -run=NONE -bench=BenchmarkLarge -count=10 ./internal/zstd"
    exit 2
fi

if [ $(git status --porcelain | wc -l) -ne "0" ]; then
    echo "Please commit your changes or stash them before you switch branches."
    exit 3
fi

readonly REVA="$1"; shift
readonly REVB="$1"; shift

readonly HEAD=$(git rev-parse --abbrev-ref HEAD)
readonly COMMITA=$(git rev-parse "$REVA")
readonly COMMITB=$(git rev-parse "$REVB")
readonly OUT=$(mktemp -d benchrev.XXXXXXXXXX)

function cleanup {
    rm -rf "$OUT"
    git checkout -q "$HEAD"
}
trap cleanup EXIT

git checkout -q "$COMMITA"
"$@" | tee "$OUT/$COMMITA"

git checkout -q "$COMMITB"
"$@" | tee "$OUT/$COMMITB"

benchstat "$REVA=$OUT/$COMMITA" "$REVB=$OUT/$COMMITB"
p5cysglq

p5cysglq3#

有趣的。我之前没有遇到过Thue-Morse序列。我对它为什么对交错有价值有一个猜测,但你能解释一下吗?
我不确定benchstat是否是放置这个问题的地方,因为这是一个从运行分析本身中分离出的问题。但我同意一些用于运行高质量基准序列的工具会很有价值。我在过去写过一些混乱的原型。

agyaoht7

agyaoht74#

Thue-Morse序列在这里并不是那么重要,你可以随意交错所有二进制数,它会产生非常类似的效果。
使用Thue-Morse可能会帮助打破噪声模式,如果偶然地,机器上的周期负载噪声与正在运行的基准(因为它们不会按顺序交错,噪声将以相似的方式影响这两个基准)。
可以说,我可以在我的shell中添加一个命令来实现:

for i in (seq 10); /tmp/old -test.bench=. | tee /dev/stderr >> /tmp/old.results; /tmp/new -test.bench=. | tee /dev/stderr >> /tmp/new.results; end; benchstat /tmp/{old,new}

但我觉得 benchstat -run -count=10 /tmp/{old,new} 是一个快速获胜的方法,也能帮助更多的人。

8iwquhpp

8iwquhpp5#

主要的比较对象是:

> go test -bench=. -count=10 | tee /tmp/new
> git checkout HEAD~1
> go test -bench=. -count=10 | tee /tmp/old
> benchstat /tmp/{old,new}

它具有明显的实际缺点。

lqfhib0f

lqfhib0f6#

我同意有一个工具来帮助运行基准测试以进行比较是非常有价值的。但是,它不应该被添加到benchstat中,因为这与benchstat的功能非常不同。它应该是一个新的工具。

在许多方面进行A/B比较也是有意义的。不仅仅是在两个二进制文件之间。从不同提交构建的两个二进制文件可能是最常见的用例,但即使如此,如果基准测试依赖于任何其他已签入的文件,也可能会产生意外的结果。七年前(!),我编写了这样一个a tool,专门用于比较git提交,但即使这样,当我试图减少重复切换git检出的时间时,也变得相当麻烦。也许有了像构建缓存、更定期的基准测试和增强的基准测试结果格式这样的东西,我们现在处于更好的位置来做这件事。

相关问题