Repository navigation
161 lines (145 loc) · 5.68 KB
/
Copy pathperf.yml
File metadata and controls
161 lines (145 loc) · 5.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
name: perf
# Records usage's startup cost for every commit that lands on main, into the
# git-notes ref `refs/notes/tak`. The data lives in this repository — there is
# no external service holding it, and `git fetch origin refs/notes/tak:refs/notes/tak`
# gets you the whole history.
#
# Only runs post-merge. A PR-time gate is the eventual goal, but a gate needs a
# baseline series to compare against, and right now there is none. This builds
# that baseline.
on:
push:
branches: ["main"]
workflow_dispatch:
permissions: {}
# Never two at once. Concurrent runs race the notes push; tak retries with a
# cat_sort_uniq merge so nothing is lost, but serialising avoids the churn.
# cancel-in-progress is off deliberately: every commit gets a measurement, and
# a cancelled run is a hole in the series.
concurrency:
group: perf
cancel-in-progress: false
env:
MBX_DISABLE: "1"
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: "0"
TAK_RUNNER: jdx-perf-v1-ubuntu24.04-x64-usage-rust1.97.1-img5263c143
jobs:
measure:
name: Measure
# Pinned to one runner class on purpose. Absolute instruction counts shift
# between machine types by more than a real regression does, so a series
# that wanders between runners is unreadable.
runs-on: [self-hosted, jdx-perf-v1]
container:
image: ghcr.io/jdx/perf-runner:jdx-perf-v1@sha256:5263c143b12ce2234e7b0b21d3d6501c2ed05837b42937d0eaeaa191cd5c8e68
options: --cpuset-cpus 0-7
timeout-minutes: 30
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
# Compile inside the pinned job container. Restoring target/ could relabel
# a binary built on another runner class as a jdx-perf-v1 measurement.
- uses: jdx/mise-action@2d8d4cafcbd33be2ea37d2b6f5ad595363d1f1ca # v5.1.1
with:
cache: false
env:
MISE_LOCKED: "1"
# cachegrind is the whole point: it counts instructions, which reproduce
# to ~0.02% run-to-run where wall clock on this same hardware moves by
# 4-20%. Without it tak still records timing, but the series stops being
# precise enough to detect anything.
- name: Install valgrind
timeout-minutes: 3
run: |
command -v valgrind || {
sudo apt-get update
sudo apt-get install -y --no-install-recommends valgrind
}
valgrind --version
- name: Runner metadata
run: |
{
echo '### Runner metadata'
echo '```text'
echo 'environment-revision: perf-runner@fd66d9b'
echo 'image: ghcr.io/jdx/perf-runner@sha256:5263c143b12ce2234e7b0b21d3d6501c2ed05837b42937d0eaeaa191cd5c8e68'
uname -a
lscpu
mise --version
rustc --version
cargo --version
valgrind --version
for zone in /sys/class/thermal/thermal_zone*/temp; do
[ -r "$zone" ] && printf '%s: %s\n' "$zone" "$(cat "$zone")"
done
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
- name: Measure and record
run: |
taskset -c 0-3 mise run perf:record
- name: Package measurement note
if: github.ref == 'refs/heads/main'
run: |
mkdir -p /tmp/tak-out
git notes --ref=tak show HEAD > /tmp/tak-out/note
git rev-parse HEAD > /tmp/tak-out/sha
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: github.ref == 'refs/heads/main'
with:
name: tak-measurement
path: /tmp/tak-out
retention-days: 1
if-no-files-found: error
- name: Summary
run: tak history >> "$GITHUB_STEP_SUMMARY"
publish:
name: Publish measurement note
needs: measure
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
steps:
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: tak-measurement
path: /tmp/tak-out
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Publish refs/notes/tak
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPOSITORY: ${{ github.repository }}
run: |
set -o pipefail
sha=$(cat /tmp/tak-out/sha)
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git fetch origin +refs/notes/tak:refs/notes/tak-remote || true
if git rev-parse --verify --quiet refs/notes/tak-remote >/dev/null; then
git update-ref refs/notes/tak refs/notes/tak-remote
fi
{
git notes --ref=tak show "$sha" 2>/dev/null || true
cat /tmp/tak-out/note
} | LC_ALL=C sort -u > /tmp/tak-out/merged-note
git notes --ref=tak add -f -F /tmp/tak-out/merged-note "$sha"
remote="https://x-access-token:${GITHUB_TOKEN}@github.com/${REPOSITORY}.git"
for attempt in 1 2 3 4 5; do
if git push --quiet "$remote" refs/notes/tak:refs/notes/tak; then
exit 0
fi
if [ "$attempt" -eq 5 ]; then
echo "::error::could not publish refs/notes/tak after five attempts"
exit 1
fi
git fetch --quiet "$remote" +refs/notes/tak:refs/notes/tak-remote
git notes --ref=tak merge -s cat_sort_uniq refs/notes/tak-remote
done