Improvements to tint perfmon
* Bump timeouts * Include changes description in results * Use median times instead of means * Use CPU time instead of real time * Bump prority of the benchmark process Change-Id: I40cb5635016fab4d6a1d1ee2434e94c120f7f6f5 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/121700 Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
c755ec54aa
commit
9dede34fc1
28
go.mod
28
go.mod
|
@ -21,63 +21,35 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.110.0 // indirect
|
|
||||||
cloud.google.com/go/bigquery v1.48.0 // indirect
|
|
||||||
cloud.google.com/go/compute v1.18.0 // indirect
|
cloud.google.com/go/compute v1.18.0 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||||
cloud.google.com/go/iam v0.12.0 // indirect
|
|
||||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
|
||||||
github.com/apache/arrow/go/v10 v10.0.1 // indirect
|
|
||||||
github.com/apache/thrift v0.18.1 // indirect
|
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.9.1 // indirect
|
|
||||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||||
github.com/goccy/go-json v0.10.1 // indirect
|
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
github.com/golang/mock v1.6.0 // indirect
|
github.com/golang/mock v1.6.0 // indirect
|
||||||
github.com/golang/protobuf v1.5.3 // indirect
|
github.com/golang/protobuf v1.5.3 // indirect
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
|
||||||
github.com/google/flatbuffers v23.3.3+incompatible // indirect
|
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.7.1 // indirect
|
github.com/googleapis/gax-go/v2 v2.7.1 // indirect
|
||||||
github.com/iancoleman/strcase v0.2.0 // indirect
|
|
||||||
github.com/julienschmidt/httprouter v1.3.0 // indirect
|
github.com/julienschmidt/httprouter v1.3.0 // indirect
|
||||||
github.com/klauspost/asmfmt v1.3.2 // indirect
|
|
||||||
github.com/klauspost/compress v1.16.3 // indirect
|
github.com/klauspost/compress v1.16.3 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
|
||||||
github.com/kr/pretty v0.3.0 // indirect
|
github.com/kr/pretty v0.3.0 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
github.com/lyft/protoc-gen-star v0.6.2 // indirect
|
|
||||||
github.com/maruel/subcommands v1.1.1 // indirect
|
github.com/maruel/subcommands v1.1.1 // indirect
|
||||||
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 // indirect
|
|
||||||
github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 // indirect
|
|
||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 // indirect
|
|
||||||
github.com/pierrec/lz4/v4 v4.1.17 // indirect
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
|
||||||
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
||||||
github.com/smartystreets/goconvey v1.7.2 // indirect
|
|
||||||
github.com/spf13/afero v1.9.5 // indirect
|
|
||||||
github.com/texttheater/golang-levenshtein v1.0.1 // indirect
|
github.com/texttheater/golang-levenshtein v1.0.1 // indirect
|
||||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||||
github.com/tklauser/numcpus v0.4.0 // indirect
|
github.com/tklauser/numcpus v0.4.0 // indirect
|
||||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||||
github.com/zeebo/xxh3 v1.0.2 // indirect
|
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
golang.org/x/crypto v0.7.0 // indirect
|
golang.org/x/crypto v0.7.0 // indirect
|
||||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
|
|
||||||
golang.org/x/mod v0.9.0 // indirect
|
|
||||||
golang.org/x/sync v0.1.0 // indirect
|
golang.org/x/sync v0.1.0 // indirect
|
||||||
golang.org/x/sys v0.6.0 // indirect
|
golang.org/x/sys v0.6.0 // indirect
|
||||||
golang.org/x/term v0.6.0 // indirect
|
golang.org/x/term v0.6.0 // indirect
|
||||||
golang.org/x/text v0.8.0 // indirect
|
golang.org/x/text v0.8.0 // indirect
|
||||||
golang.org/x/tools v0.7.0 // indirect
|
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
|
||||||
google.golang.org/appengine v1.6.8-0.20221117013220-504804fb50de // indirect
|
google.golang.org/appengine v1.6.8-0.20221117013220-504804fb50de // indirect
|
||||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
|
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
|
||||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 // indirect
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
||||||
exclude github.com/sergi/go-diff v1.2.0
|
exclude github.com/sergi/go-diff v1.2.0
|
||||||
|
|
|
@ -145,7 +145,7 @@ func parseJSON(s string) (Run, error) {
|
||||||
} `json:"context"`
|
} `json:"context"`
|
||||||
Benchmarks []struct {
|
Benchmarks []struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Time float64 `json:"real_time"`
|
Time float64 `json:"cpu_time"`
|
||||||
AggregateType AggregateType `json:"aggregate_name"`
|
AggregateType AggregateType `json:"aggregate_name"`
|
||||||
} `json:"benchmarks"`
|
} `json:"benchmarks"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ func TestParseJson(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedDate, err := time.Parse(time.RFC1123, "Mon, 24 Jan 2022 10:28:13 GMT")
|
expectedDate, err := time.Parse(time.RFC3339, "2022-01-24T10:28:13+00:00")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("time.Parse() returned %v", err)
|
t.Errorf("time.Parse() returned %v", err)
|
||||||
return
|
return
|
||||||
|
@ -149,11 +149,11 @@ func TestParseJson(t *testing.T) {
|
||||||
|
|
||||||
expect := bench.Run{
|
expect := bench.Run{
|
||||||
Benchmarks: []bench.Benchmark{
|
Benchmarks: []bench.Benchmark{
|
||||||
{Name: "MyBenchmark", Duration: time.Nanosecond * 1639227, AggregateType: ""},
|
{Name: "MyBenchmark", Duration: time.Nanosecond * 1638741, AggregateType: ""},
|
||||||
{Name: "MyBenchmark", Duration: time.Nanosecond * 1714393, AggregateType: ""},
|
{Name: "MyBenchmark", Duration: time.Nanosecond * 1712400, AggregateType: ""},
|
||||||
{Name: "MyBenchmark", Duration: time.Nanosecond * 1676810, AggregateType: "mean"},
|
{Name: "MyBenchmark", Duration: time.Nanosecond * 1675570, AggregateType: "mean"},
|
||||||
{Name: "MyBenchmark", Duration: time.Nanosecond * 1676810, AggregateType: "median"},
|
{Name: "MyBenchmark", Duration: time.Nanosecond * 1675570, AggregateType: "median"},
|
||||||
{Name: "MyBenchmark", Duration: time.Nanosecond * 53150, AggregateType: "stddev"},
|
{Name: "MyBenchmark", Duration: time.Nanosecond * 52084, AggregateType: "stddev"},
|
||||||
},
|
},
|
||||||
Context: &bench.Context{
|
Context: &bench.Context{
|
||||||
Date: expectedDate,
|
Date: expectedDate,
|
||||||
|
@ -171,7 +171,7 @@ func TestParseJson(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
expectEqual(t, "bench.Parse().Benchmarks", got.Benchmarks, expect.Benchmarks)
|
expectEqual(t, "bench.Parse().Benchmarks", got.Benchmarks, expect.Benchmarks)
|
||||||
expectEqual(t, "bench.Parse().Context", got.Benchmarks, expect.Benchmarks)
|
expectEqual(t, "bench.Parse().Context", got.Context, expect.Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompare(t *testing.T) {
|
func TestCompare(t *testing.T) {
|
||||||
|
|
|
@ -223,10 +223,10 @@ func (cfg *GitConfig) setDefaults() {
|
||||||
// setDefaults assigns default values to unassigned fields of cfg
|
// setDefaults assigns default values to unassigned fields of cfg
|
||||||
func (cfg *TimeoutsConfig) setDefaults() {
|
func (cfg *TimeoutsConfig) setDefaults() {
|
||||||
if cfg.Sync == 0 {
|
if cfg.Sync == 0 {
|
||||||
cfg.Sync = time.Minute * 10
|
cfg.Sync = time.Minute * 30
|
||||||
}
|
}
|
||||||
if cfg.Build == 0 {
|
if cfg.Build == 0 {
|
||||||
cfg.Build = time.Minute * 10
|
cfg.Build = time.Minute * 30
|
||||||
}
|
}
|
||||||
if cfg.Benchmark == 0 {
|
if cfg.Benchmark == 0 {
|
||||||
cfg.Benchmark = time.Minute * 30
|
cfg.Benchmark = time.Minute * 30
|
||||||
|
@ -327,12 +327,12 @@ func (e env) doSomeWork() (bool, error) {
|
||||||
log.Printf("benchmarked %v changes", i)
|
log.Printf("benchmarked %v changes", i)
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
benchRes, err := e.benchmarkTintChange(c)
|
benchRes, err := e.benchmarkTintChange(c.hash, c.desc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("benchmarking failed: %v", err)
|
log.Printf("benchmarking failed: %v", err)
|
||||||
benchRes = &bench.Run{}
|
benchRes = &bench.Run{}
|
||||||
}
|
}
|
||||||
commitRes, err := e.benchmarksToCommitResults(c, *benchRes)
|
commitRes, err := e.benchmarksToCommitResults(c.hash, *benchRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, err
|
return true, err
|
||||||
}
|
}
|
||||||
|
@ -353,13 +353,13 @@ func (e env) doSomeWork() (bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if changeToBenchmark != nil {
|
if changeToBenchmark != nil {
|
||||||
log.Printf("re-benchmarking change '%v'", *changeToBenchmark)
|
log.Printf("re-benchmarking change '%v'", changeToBenchmark.hash)
|
||||||
benchRes, err := e.benchmarkTintChange(*changeToBenchmark)
|
benchRes, err := e.benchmarkTintChange(changeToBenchmark.hash, changeToBenchmark.desc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("benchmarking failed: %v", err)
|
log.Printf("benchmarking failed: %v", err)
|
||||||
benchRes = &bench.Run{}
|
benchRes = &bench.Run{}
|
||||||
}
|
}
|
||||||
commitRes, err := e.benchmarksToCommitResults(*changeToBenchmark, *benchRes)
|
commitRes, err := e.benchmarksToCommitResults(changeToBenchmark.hash, *benchRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, err
|
return true, err
|
||||||
}
|
}
|
||||||
|
@ -373,9 +373,15 @@ func (e env) doSomeWork() (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HashAndDesc describes a single change to benchmark
|
||||||
|
type HashAndDesc struct {
|
||||||
|
hash git.Hash
|
||||||
|
desc string
|
||||||
|
}
|
||||||
|
|
||||||
// changesToBenchmark fetches the list of changes that do not currently have
|
// changesToBenchmark fetches the list of changes that do not currently have
|
||||||
// benchmark results, which should be benchmarked.
|
// benchmark results, which should be benchmarked.
|
||||||
func (e env) changesToBenchmark() ([]git.Hash, error) {
|
func (e env) changesToBenchmark() ([]HashAndDesc, error) {
|
||||||
log.Println("syncing dawn repo...")
|
log.Println("syncing dawn repo...")
|
||||||
latest, err := e.dawnRepo.Fetch(e.cfg.Dawn.Branch, &git.FetchOptions{
|
latest, err := e.dawnRepo.Fetch(e.cfg.Dawn.Branch, &git.FetchOptions{
|
||||||
Credentials: e.cfg.Dawn.Credentials,
|
Credentials: e.cfg.Dawn.Credentials,
|
||||||
|
@ -394,10 +400,10 @@ func (e env) changesToBenchmark() ([]git.Hash, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to gather changes with existing benchmarks:\n %w", err)
|
return nil, fmt.Errorf("failed to gather changes with existing benchmarks:\n %w", err)
|
||||||
}
|
}
|
||||||
changesToBenchmark := make([]git.Hash, 0, len(allChanges))
|
changesToBenchmark := make([]HashAndDesc, 0, len(allChanges))
|
||||||
for _, c := range allChanges {
|
for _, c := range allChanges {
|
||||||
if _, exists := changesWithBenchmarks[c.Hash]; !exists {
|
if _, exists := changesWithBenchmarks[c.Hash]; !exists {
|
||||||
changesToBenchmark = append(changesToBenchmark, c.Hash)
|
changesToBenchmark = append(changesToBenchmark, HashAndDesc{c.Hash, c.Subject})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Reverse the order of changesToBenchmark, so that the oldest comes first.
|
// Reverse the order of changesToBenchmark, so that the oldest comes first.
|
||||||
|
@ -412,7 +418,7 @@ func (e env) changesToBenchmark() ([]git.Hash, error) {
|
||||||
// changeToRefineBenchmarks scans for the most suitable historic commit to
|
// changeToRefineBenchmarks scans for the most suitable historic commit to
|
||||||
// re-benchmark and refine the results. Returns nil if there are no suitable
|
// re-benchmark and refine the results. Returns nil if there are no suitable
|
||||||
// changes.
|
// changes.
|
||||||
func (e env) changeToRefineBenchmarks() (*git.Hash, error) {
|
func (e env) changeToRefineBenchmarks() (*HashAndDesc, error) {
|
||||||
log.Println("syncing results repo...")
|
log.Println("syncing results repo...")
|
||||||
if err := fetchAndCheckoutLatest(e.resultsRepo, e.cfg.Results); err != nil {
|
if err := fetchAndCheckoutLatest(e.resultsRepo, e.cfg.Results); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -433,11 +439,11 @@ func (e env) changeToRefineBenchmarks() (*git.Hash, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type hashDelta struct {
|
type changeDelta struct {
|
||||||
hash git.Hash
|
change HashAndDesc
|
||||||
delta float64
|
delta float64
|
||||||
}
|
}
|
||||||
hashDeltas := make([]hashDelta, 0, len(results.Commits))
|
hashDeltas := make([]changeDelta, 0, len(results.Commits))
|
||||||
for i, c := range results.Commits {
|
for i, c := range results.Commits {
|
||||||
hash, err := git.ParseHash(c.Commit)
|
hash, err := git.ParseHash(c.Commit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -465,31 +471,32 @@ func (e env) changeToRefineBenchmarks() (*git.Hash, error) {
|
||||||
}
|
}
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
delta = delta / float64(count)
|
delta = delta / float64(count)
|
||||||
hashDeltas = append(hashDeltas, hashDelta{hash, delta})
|
desc := strings.Split(c.CommitDescription, "\n")[0]
|
||||||
|
hashDeltas = append(hashDeltas, changeDelta{HashAndDesc{hash, desc}, delta})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Slice(hashDeltas, func(i, j int) bool { return hashDeltas[i].delta > hashDeltas[j].delta })
|
sort.Slice(hashDeltas, func(i, j int) bool { return hashDeltas[i].delta > hashDeltas[j].delta })
|
||||||
|
|
||||||
return &hashDeltas[0].hash, nil
|
return &hashDeltas[0].change, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// benchmarkTintChangeIfNotCached first checks the results cache for existing
|
// benchmarkTintChangeIfNotCached first checks the results cache for existing
|
||||||
// benchmark values for the given change, returning those cached values if hit.
|
// benchmark values for the given change, returning those cached values if hit.
|
||||||
// If the cache does not contain results for the change, then
|
// If the cache does not contain results for the change, then
|
||||||
// e.benchmarkTintChange() is called.
|
// e.benchmarkTintChange() is called.
|
||||||
func (e env) benchmarkTintChangeIfNotCached(hash git.Hash) (*bench.Run, error) {
|
func (e env) benchmarkTintChangeIfNotCached(hash git.Hash, desc string) (*bench.Run, error) {
|
||||||
if cached, ok := e.benchmarkCache[hash]; ok {
|
if cached, ok := e.benchmarkCache[hash]; ok {
|
||||||
log.Printf("reusing cached benchmark results of '%v'...", hash)
|
log.Printf("reusing cached benchmark results of '%v'...", hash)
|
||||||
return cached, nil
|
return cached, nil
|
||||||
}
|
}
|
||||||
return e.benchmarkTintChange(hash)
|
return e.benchmarkTintChange(hash, desc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// benchmarkTintChange checks out the given commit, fetches the dawn third party
|
// benchmarkTintChange checks out the given commit, fetches the dawn third party
|
||||||
// dependencies, builds tint, then runs the benchmarks, returning the results.
|
// dependencies, builds tint, then runs the benchmarks, returning the results.
|
||||||
func (e env) benchmarkTintChange(hash git.Hash) (*bench.Run, error) {
|
func (e env) benchmarkTintChange(hash git.Hash, desc string) (*bench.Run, error) {
|
||||||
log.Printf("checking out dawn at '%v'...", hash)
|
log.Printf("checking out dawn at '%v': %v...", hash, desc)
|
||||||
if err := checkout(hash, e.dawnRepo); err != nil {
|
if err := checkout(hash, e.dawnRepo); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -769,15 +776,10 @@ func (e errFailedToBenchmark) Error() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// benchmarkTint runs the tint benchmarks e.cfg.BenchmarkRepetitions times,
|
// benchmarkTint runs the tint benchmarks e.cfg.BenchmarkRepetitions times,
|
||||||
// returning the averaged results.
|
// returning the median timing.
|
||||||
func (e env) repeatedlyBenchmarkTint() (*bench.Run, error) {
|
func (e env) repeatedlyBenchmarkTint() (*bench.Run, error) {
|
||||||
type durationAndCount struct {
|
|
||||||
duration time.Duration
|
|
||||||
count int
|
|
||||||
}
|
|
||||||
|
|
||||||
var ctx *bench.Context
|
var ctx *bench.Context
|
||||||
acc := map[string]durationAndCount{}
|
testTimes := map[string][]time.Duration{}
|
||||||
for i := 0; i < e.cfg.BenchmarkRepetitions; i++ {
|
for i := 0; i < e.cfg.BenchmarkRepetitions; i++ {
|
||||||
if err := e.waitForTempsToSettle(); err != nil {
|
if err := e.waitForTempsToSettle(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -788,10 +790,7 @@ func (e env) repeatedlyBenchmarkTint() (*bench.Run, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, b := range run.Benchmarks {
|
for _, b := range run.Benchmarks {
|
||||||
v := acc[b.Name]
|
testTimes[b.Name] = append(testTimes[b.Name], b.Duration)
|
||||||
v.duration += b.Duration
|
|
||||||
v.count++
|
|
||||||
acc[b.Name] = v
|
|
||||||
}
|
}
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
ctx = run.Context
|
ctx = run.Context
|
||||||
|
@ -799,10 +798,11 @@ func (e env) repeatedlyBenchmarkTint() (*bench.Run, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
out := bench.Run{Context: ctx}
|
out := bench.Run{Context: ctx}
|
||||||
for name, dc := range acc {
|
for name, times := range testTimes {
|
||||||
|
sort.Slice(times, func(i, j int) bool { return times[i] < times[j] })
|
||||||
out.Benchmarks = append(out.Benchmarks, bench.Benchmark{
|
out.Benchmarks = append(out.Benchmarks, bench.Benchmark{
|
||||||
Name: name,
|
Name: name,
|
||||||
Duration: dc.duration / time.Duration(dc.count),
|
Duration: times[len(times)/2], // Median
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -817,12 +817,12 @@ func (e env) benchmarkTint() (*bench.Run, error) {
|
||||||
"--benchmark_enable_random_interleaving=true",
|
"--benchmark_enable_random_interleaving=true",
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errFailedToBenchmark{err}
|
return nil, errFailedToBenchmark{fmt.Errorf("failed to run benchmarks: %w\noutput: %v", err, out)}
|
||||||
}
|
}
|
||||||
|
|
||||||
results, err := bench.Parse(out)
|
results, err := bench.Parse(out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errFailedToBenchmark{err}
|
return nil, errFailedToBenchmark{fmt.Errorf("failed to parse benchmark results: %w\noutput: %v", err, out)}
|
||||||
}
|
}
|
||||||
return &results, nil
|
return &results, nil
|
||||||
}
|
}
|
||||||
|
@ -930,6 +930,7 @@ func (e env) findGerritChangeToBenchmark() (*gerrit.ChangeInfo, error) {
|
||||||
// benchmarks the gerrit change, posting the findings to the change
|
// benchmarks the gerrit change, posting the findings to the change
|
||||||
func (e env) benchmarkGerritChange(change gerrit.ChangeInfo) error {
|
func (e env) benchmarkGerritChange(change gerrit.ChangeInfo) error {
|
||||||
current := change.Revisions[change.CurrentRevision]
|
current := change.Revisions[change.CurrentRevision]
|
||||||
|
fmt.Println("benchmarking", change.URL)
|
||||||
log.Printf("fetching '%v'...", current.Ref)
|
log.Printf("fetching '%v'...", current.Ref)
|
||||||
currentHash, err := e.dawnRepo.Fetch(current.Ref, &git.FetchOptions{
|
currentHash, err := e.dawnRepo.Fetch(current.Ref, &git.FetchOptions{
|
||||||
Credentials: e.cfg.Dawn.Credentials,
|
Credentials: e.cfg.Dawn.Credentials,
|
||||||
|
@ -937,8 +938,8 @@ func (e env) benchmarkGerritChange(change gerrit.ChangeInfo) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
parent := current.Commit.Parents[0].Commit
|
parent := current.Commit.Parents[0]
|
||||||
parentHash, err := git.ParseHash(parent)
|
parentHash, err := git.ParseHash(parent.Commit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to parse parent hash '%v':\n %v", parent, err)
|
return fmt.Errorf("failed to parse parent hash '%v':\n %v", parent, err)
|
||||||
}
|
}
|
||||||
|
@ -955,7 +956,7 @@ func (e env) benchmarkGerritChange(change gerrit.ChangeInfo) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
newRun, err := e.benchmarkTintChange(currentHash)
|
newRun, err := e.benchmarkTintChange(currentHash, change.Subject)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("ERROR: %v", err)
|
log.Printf("ERROR: %v", err)
|
||||||
buildErr := errFailedToBuild{}
|
buildErr := errFailedToBuild{}
|
||||||
|
@ -968,12 +969,13 @@ func (e env) benchmarkGerritChange(change gerrit.ChangeInfo) error {
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := e.dawnRepo.Fetch(parent, &git.FetchOptions{
|
if _, err := e.dawnRepo.Fetch(parent.Commit, &git.FetchOptions{
|
||||||
Credentials: e.cfg.Dawn.Credentials,
|
Credentials: e.cfg.Dawn.Credentials,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
parentRun, err := e.benchmarkTintChangeIfNotCached(parentHash)
|
parentRun, err := e.benchmarkTintChangeIfNotCached(parentHash,
|
||||||
|
fmt.Sprintf("[parent of %v] %v", currentHash.String()[:7], parent.Subject))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -993,7 +995,7 @@ func (e env) benchmarkGerritChange(change gerrit.ChangeInfo) error {
|
||||||
fmt.Fprintln(msg, "Perfmon analysis:")
|
fmt.Fprintln(msg, "Perfmon analysis:")
|
||||||
fmt.Fprintln(msg)
|
fmt.Fprintln(msg)
|
||||||
fmt.Fprintln(msg, "```")
|
fmt.Fprintln(msg, "```")
|
||||||
fmt.Fprintf(msg, "A: parent change (%v) -> B: patchset %v\n", parent[:7], current.Number)
|
fmt.Fprintf(msg, "A: parent change (%v) -> B: patchset %v\n", parent.Commit[:7], current.Number)
|
||||||
fmt.Fprintln(msg)
|
fmt.Fprintln(msg)
|
||||||
for _, line := range strings.Split(diff.Format(diffFmt), "\n") {
|
for _, line := range strings.Split(diff.Format(diffFmt), "\n") {
|
||||||
fmt.Fprintf(msg, " %v\n", line)
|
fmt.Fprintf(msg, " %v\n", line)
|
||||||
|
@ -1199,10 +1201,15 @@ func maxTemp(sensorName string) (float32, error) {
|
||||||
func call(exe, wd string, timeout time.Duration, args ...string) (string, error) {
|
func call(exe, wd string, timeout time.Duration, args ...string) (string, error) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
cmd := exec.CommandContext(ctx, exe, args...)
|
args = append([]string{"-n", "-20", exe}, args...)
|
||||||
|
cmd := exec.CommandContext(ctx, "nice", args...)
|
||||||
cmd.Dir = wd
|
cmd.Dir = wd
|
||||||
out, err := cmd.CombinedOutput()
|
out, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// Note: If you get a permission error with 'nice', then you either need
|
||||||
|
// to run as sudo (not recommended), or update your ulimits:
|
||||||
|
// Append to /etc/security/limits.conf:
|
||||||
|
// <user> - nice -20
|
||||||
return string(out), fmt.Errorf("'%v %v' failed:\n %w\n%v", exe, args, err, string(out))
|
return string(out), fmt.Errorf("'%v %v' failed:\n %w\n%v", exe, args, err, string(out))
|
||||||
}
|
}
|
||||||
return string(out), nil
|
return string(out), nil
|
||||||
|
|
Loading…
Reference in New Issue