Skip to content

Commit

Permalink
PGO: optimize collected profile file size (#14256) (#14267)
Browse files Browse the repository at this point in the history
(cherry picked from commit 3833927)

# Conflicts:
#	.github/workflows/benchmarks.yml
#	systemtest/benchtest/profiles.go
#	testing/benchmark/Makefile

Co-authored-by: Kostiantyn Masliuk <[email protected]>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
mergify[bot] and 1pkg authored Oct 11, 2024
1 parent 05081aa commit 7097284
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ jobs:
git_commit_gpgsign: true

- name: Open PGO PR
if: ${{ env.RUN_STANDALONE == 'true' && github.ref == 'refs/heads/main' }}
if: ${{ env.RUN_STANDALONE == 'true' }}
run: ${{ github.workspace }}/.ci/scripts/push-pgo-pr.sh
env:
WORKSPACE_PATH: ${{ github.workspace }}
Expand Down
41 changes: 31 additions & 10 deletions systemtest/benchtest/profiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
package benchtest

import (
"compress/gzip"
"context"
"fmt"
"io"
"math/rand/v2"
"net/http"
"os"
"strconv"
Expand Down Expand Up @@ -88,12 +90,30 @@ func (p *profiles) recordCPU() error {
if benchConfig.CPUProfile == "" {
return nil
}
duration := benchConfig.Benchtime
profile, err := fetchProfile("/debug/pprof/profile", duration)
if err != nil {
return fmt.Errorf("failed to fetch CPU profile: %w", err)
// Limit profiling time to random 5% of overall time.
// This should not seriously affect the profile quality,
// since we merge the final profile form multiple sources,
// but prevent profile size from swelling.
var done bool
const tickets = 20
duration := benchConfig.Benchtime / tickets
for i := range tickets {
if done || (rand.N(tickets-i)+i+1) < tickets {
time.Sleep(duration)
continue
}
profile, err := fetchProfile("/debug/pprof/profile", duration)
if err != nil {
return fmt.Errorf("failed to fetch CPU profile: %w", err)
}
// We don't need the address in the profile, so discard it to reduce the size.
if err := profile.Aggregate(true, true, true, true, false); err != nil {
return fmt.Errorf("failed to fetch CPU profile: %w", err)
}
profile = profile.Compact()
p.cpu = append(p.cpu, profile)
done = true
}
p.cpu = append(p.cpu, profile)
return nil
}

Expand Down Expand Up @@ -168,14 +188,15 @@ func (p *profiles) writeDeltas(filename string, deltas []*profile.Profile) error
return err
}
defer f.Close()
return merged.Write(f)
w, err := gzip.NewWriterLevel(f, gzip.BestCompression)
if err != nil {
return err
}
defer w.Close()
return merged.WriteUncompressed(w)
}

func (p *profiles) mergeBenchmarkProfiles(profiles []*profile.Profile) (*profile.Profile, error) {
for i, profile := range profiles {
benchmarkName := p.benchmarkNames[i]
profile.SetLabel("benchmark", []string{benchmarkName})
}
merged, err := profile.Merge(profiles)
if err != nil {
return nil, fmt.Errorf("error merging profiles: %w", err)
Expand Down
1 change: 0 additions & 1 deletion testing/benchmark/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ SSH_OPTS ?= -o LogLevel=ERROR -o StrictHostKeyChecking=no -o ServerAliveInterval
SSH_KEY ?= ~/.ssh/id_rsa_terraform
WORKER_IP = $(shell terraform output -raw public_ip)
APM_SERVER_IP = $(shell terraform output -raw apm_server_ip)
RUN_STANDALONE = $(shell echo var.run_standalone | terraform console | tr -d '"')

SHELL = /bin/bash
.SHELLFLAGS = -o pipefail -c
Expand Down

0 comments on commit 7097284

Please sign in to comment.