Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2ee0744
runtime,cl: stack-keyed sampled memory profiling with gc semantics
cpunion Jul 4, 2026
d9c3ae0
test: memprofile attribution regressions; retire heapsampling xfails
cpunion Jul 4, 2026
f8c9798
runtime: never wait on the frame-table init latch from the memprofile…
cpunion Jul 5, 2026
685ca14
test: cover memprofile package detection paths
cpunion Jul 20, 2026
b83f8e3
runtime: initialize frame metadata before memory sampling
cpunion Jul 20, 2026
b2406f0
test: cover memprofile detection without package metadata
cpunion Jul 20, 2026
3fb591c
runtime: share prefix helper with wasm
cpunion Jul 29, 2026
c75decd
runtime: make memory profile sampling concurrency-safe
cpunion Aug 10, 2026
e544e08
runtime,cl: adapt memory profiling to current main
cpunion Aug 17, 2026
0dbef80
runtime: reduce memory profiler TLS hot-path overhead
cpunion Aug 17, 2026
a6f9991
test: refresh module path expectations
zhouguangyuan0718 Aug 17, 2026
3859c4d
runtime: minimize sampled heap profiling overhead
cpunion Aug 17, 2026
1248692
ssa,cl: reuse native TLS addresses on hot paths
cpunion Aug 17, 2026
26ddb05
cl,build: omit unused memory profiling hooks
cpunion Aug 17, 2026
0876322
cl,runtime: omit unused memory profile setup
cpunion Aug 17, 2026
e98d946
test: stabilize memory profile rate transition
cpunion Aug 17, 2026
22e3d20
test: materialize memory profile size samples
cpunion Aug 17, 2026
7b1e320
benchmark: stabilize and track memory profile paths
cpunion Aug 18, 2026
2c18656
benchmark: publish stable profile workloads
cpunion Aug 18, 2026
ceb4754
benchmark: interleave pull request comparisons
cpunion Aug 18, 2026
94289e3
benchmark: pair individual microbenchmarks
cpunion Aug 18, 2026
d268ae6
benchmark: alternate program revision order
cpunion Aug 18, 2026
341531c
ci: allow benchmark setup variance
cpunion Aug 18, 2026
e67b507
ci: use setup-benchmark-go-action v1.0.5
cpunion Aug 18, 2026
05367fb
ci: pin benchmark action v1.0.5
cpunion Aug 18, 2026
a7bafd4
runtime: fix trace stop deadlock on Go 1.25
visualfc Aug 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/benchmark-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ permissions:
jobs:
publish:
if: github.event.workflow_run.conclusion == 'success'
uses: xgo-dev/setup-benchmark-go-action/.github/workflows/publish.yml@v1.0.4
uses: xgo-dev/setup-benchmark-go-action/.github/workflows/publish.yml@v1.0.5
with:
run_id: ${{ github.event.workflow_run.id }}
config_path: .github/llgo-benchmark.yml
42 changes: 22 additions & 20 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
id: macos
display: macOS
runs-on: ${{ matrix.os }}
timeout-minutes: 20
timeout-minutes: 30
env:
GOMAXPROCS: "2"
LLGO_ROOT: ${{ github.workspace }}
Expand All @@ -38,7 +38,16 @@ jobs:
with:
repository: ${{ github.event.pull_request.base.repo.full_name }}
ref: ${{ github.event.pull_request.base.sha }}
path: .benchmark/source
path: .benchmark/base-source
persist-credentials: false

- name: Check out pull request head benchmark source
if: github.event_name == 'pull_request'
uses: actions/checkout@v7
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.sha }}
path: .benchmark/head-source
persist-credentials: false

- name: Install dependencies
Expand All @@ -49,41 +58,34 @@ jobs:
- name: Set up Go
uses: ./.github/actions/setup-go

- name: Measure pull request base
- name: Measure paired pull request revisions
if: github.event_name == 'pull_request'
run: |
benchmark/baseline/run.sh \
"$GITHUB_WORKSPACE/.benchmark/source" \
"$GITHUB_WORKSPACE/.benchmark/base-source" \
"$GITHUB_WORKSPACE/.benchmark/base-llgo" \
"$GITHUB_WORKSPACE/.benchmark/base-results"

- name: Check out pull request head benchmark source
if: github.event_name == 'pull_request'
uses: actions/checkout@v7
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.sha }}
path: .benchmark/source
persist-credentials: false
"$GITHUB_WORKSPACE/.benchmark/base-results" \
"$GITHUB_WORKSPACE/.benchmark/head-source" \
"$GITHUB_WORKSPACE/.benchmark/llgo" \
"$GITHUB_WORKSPACE/.benchmark/results"

- name: Measure current revision
if: github.event_name != 'pull_request'
run: |
source_root="$GITHUB_WORKSPACE"
if [[ "$GITHUB_EVENT_NAME" == pull_request ]]; then
source_root="$GITHUB_WORKSPACE/.benchmark/source"
fi
benchmark/baseline/run.sh \
"$source_root" \
"$GITHUB_WORKSPACE" \
"$GITHUB_WORKSPACE/.benchmark/llgo" \
"$GITHUB_WORKSPACE/.benchmark/results"

- name: Record benchmark result
uses: xgo-dev/setup-benchmark-go-action@v1.0.4
uses: xgo-dev/setup-benchmark-go-action@v1.0.5
with:
config: .github/llgo-benchmark.yml
benchmark-file: .benchmark/results/benchmark.txt
baseline-benchmark-file: >-
${{ github.event_name == 'pull_request' &&
'.benchmark/base-results/benchmark.txt' || '' }}
sample-pairing: >-
${{ github.event_name == 'pull_request' && 'index' || '' }}
platform-id: ${{ matrix.id }}
platform-label: ${{ matrix.display }}
81 changes: 33 additions & 48 deletions benchmark/baseline/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# LLGo baseline benchmarks

This suite is the lightweight performance gate for ordinary LLGo changes. It
uses fixed workloads and short calibrated benchmarks on Linux and macOS so it
uses fixed workloads and calibrated benchmarks on Linux and macOS so it
can run on every `main` push and pull request. Branch-only series can be run
explicitly with `workflow_dispatch`, avoiding duplicate push and pull-request
jobs for the same commit. The two native jobs record normalized artifacts; a
Expand All @@ -15,22 +15,33 @@ The program workloads reuse:
- `benchmark/binary_size/fmtprintf`: `fmt.Printf`.

For each workload, the collector performs an unmeasured warm build, then records
median build time, median process time, file size, executable-code bytes,
allocated non-executable data, and zero-filled data. On ELF, read-only constants
are included in the data bucket; on Mach-O, `__TEXT` constants are included in
the text bucket. The Go benchmark stream records five samples of selected
compiler helpers and LLGo-generated core-language operations: direct/interface
calls, defer, goroutine creation, channels, `getg`, and global access.
the median of six builds and eighteen process runs, file size, executable-code
bytes, allocated non-executable data, and zero-filled data. Workload order is
rotated between rounds to balance runner drift and cache position. On ELF,
read-only constants are included in the data bucket; on Mach-O, `__TEXT`
constants are included in the text bucket. The Go benchmark stream performs one
unrecorded warmup, then records seven one-second samples of compiler helpers and
LLGo-generated core-language operations: direct/interface calls, defer,
channels, `getg`, and global access. Goroutine creation keeps its bounded
100-iteration samples.

For pull requests, each platform job checks out the recorded base and current
commits into the same source path, then runs both suites sequentially on the same
runner. The pull request comment compares that pair, avoiding differences from
runner machines and embedded source paths. Dependency setup is shared, and Go's
build cache can be reused by unchanged packages; main pushes still run the suite
only once. Very small changes can still be scheduler, frequency, or thermal
noise and should be confirmed by repeated workflow runs. If a workflow does not
provide a paired result, the publisher falls back to the latest matching `main`
data.
The program table also includes standalone memory-profile workloads so the
whole-program no-consumer path is measurable independently of the retained
profile paths. Every process disables BDWGC, warms with two million allocations,
then internally times forty million escaping 16-byte allocations. The reported
duration is the median of eighteen processes. The workloads are
`memprofile-no-consumer`, `memprofile-rate0`, and `memprofile-default`.

For pull requests, each platform job builds the recorded base and current
revisions on one runner, then alternates their measurements within every round.
Compiler and runtime benchmark binaries are built before sampling, so only their
execution is interleaved and each matching base/current sample remains adjacent.
This prevents a phase-wide frequency, thermal, or host load change from being
attributed entirely to one revision. Dependency setup is shared, and Go's build
cache can be reused by unchanged packages; main pushes still run the suite only
once. Very small changes can remain scheduler noise and should be confirmed by
repeated workflow runs. If a workflow does not provide a paired result, the
publisher falls back to the latest matching `main` data.

The trusted publisher commits the current result history and generated site to
the `pages` branch of the configured data repository. Every LLGo repository
Expand All @@ -48,39 +59,13 @@ updated summary comment linking to their long-term trend page. If no matching
`main` history exists yet, the pull-request report is still published and
marks every metric as `new`.

Local collection:

```sh
GOMAXPROCS=2 go build -o .benchmark/llgo ./cmd/llgo
go run ./benchmark/baseline \
-llgo .benchmark/llgo \
-out .benchmark/results
```

Write the selected Go benchmark output to `.benchmark/results/go.txt`:
Run the complete local collection with the same script as CI:

```sh
results=.benchmark/results/go.txt
GOMAXPROCS=1 go test \
-run '^$' \
-bench '^(BenchmarkMergeCompilerFlags|BenchmarkMergeLinkerFlags|BenchmarkLookupPCRandom)$' \
-benchtime=250ms -count=5 -cpu=1 \
./internal/clang ./internal/build/funcinfo | tee "$results"
GOMAXPROCS=1 .benchmark/llgo test \
-run '^$' \
-bench '^(BenchmarkRuntimeGetG|BenchmarkGlobal(Read|Write)|Benchmark(DirectCall|InterfaceCall|Defer|ChannelBuffered|ChannelHandoff))$' \
-benchtime=250ms -count=5 \
./test/llgoext | tee -a "$results"
GOMAXPROCS=1 .benchmark/llgo test \
-run '^$' -bench '^BenchmarkGoroutine$' -benchtime=100x -count=5 \
./test/llgoext | tee -a "$results"
benchmark/baseline/run.sh \
"$PWD" \
"$PWD/.benchmark/llgo" \
"$PWD/.benchmark/results"
```

Then validate and export the complete artifact in standard Go benchmark format:

```sh
go run ./benchmark/baseline \
-mode export \
-out .benchmark/results \
-benchmark-output .benchmark/results/benchmark.txt
```
The normalized artifact is `.benchmark/results/benchmark.txt`.
Loading
Loading