Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
89 changes: 89 additions & 0 deletions .github/workflows/codspeed.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: CodSpeed

on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:

permissions:
contents: read
id-token: write

env:
CARGO_INCREMENTAL: 0
CARGO_NET_RETRY: 10
RUSTUP_MAX_RETRIES: 10
RUST_BACKTRACE: short
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1
CARGO_PROFILE_DEV_DEBUG: 0

jobs:
simulation:
name: CodSpeed simulation
if: vars.CODSPEED_ENABLED == 'true'
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v6

- name: Install build dependencies
uses: ./.github/actions/install-build-deps

- name: Rust cache
uses: Swatinem/rust-cache@v2.9.1

- name: Corpus cache
uses: actions/cache@v5
with:
path: ./bench-data/wireshark-rdp
key: ${{ runner.os }}-codspeed-corpus-${{ hashFiles('crates/ironrdp-bench/corpus.toml') }}

- name: Fetch corpus
run: cargo xtask bench corpus-fetch

- name: Install cargo-codspeed
run: cargo install cargo-codspeed --version 5.0.1 --locked

- name: Build benchmarks
run: cargo codspeed build -p ironrdp-bench --bench bench --bench capture_replay --features codspeed --locked -m simulation

- name: Measure benchmarks
uses: CodSpeedHQ/action@v5
with:
mode: simulation
run: cargo codspeed run -p ironrdp-bench --bench bench --bench capture_replay -m simulation

walltime:
name: CodSpeed walltime
if: github.event_name == 'workflow_dispatch' && vars.CODSPEED_ENABLED == 'true' && vars.CODSPEED_WALLTIME_RUNNER != ''
runs-on: ${{ vars.CODSPEED_WALLTIME_RUNNER }}

steps:
- uses: actions/checkout@v6

- name: Install build dependencies
uses: ./.github/actions/install-build-deps

- name: Rust cache
uses: Swatinem/rust-cache@v2.9.1

- name: Corpus cache
uses: actions/cache@v5
with:
path: ./bench-data/wireshark-rdp
key: ${{ runner.os }}-codspeed-corpus-${{ hashFiles('crates/ironrdp-bench/corpus.toml') }}

- name: Fetch corpus
run: cargo xtask bench corpus-fetch
Comment thread
CBenoit marked this conversation as resolved.

- name: Build replay command
run: cargo build --release -p ironrdp-bench --bin capture-replay-bench --locked

- name: Measure replay commands
uses: CodSpeedHQ/action@v5
with:
mode: walltime
123 changes: 120 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions codspeed.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
benchmarks:
- name: partial-replay/no-nla-accepted/strict-cli
exec: ./target/release/capture-replay-bench --capture no-nla-accepted

- name: partial-replay/no-nla-smartcard/strict-cli
exec: ./target/release/capture-replay-bench --capture no-nla-smartcard

- name: connector-replay/no-nla-accepted/strict-cli
exec: ./target/release/capture-replay-bench --connector no-nla-accepted
2 changes: 2 additions & 0 deletions crates/ironrdp-bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ publish = false
default = ["qoi", "qoiz"]
qoi = ["ironrdp/qoi"]
qoiz = ["ironrdp/qoiz"]
codspeed = ["dep:codspeed-criterion-compat"]

[dependencies]
anyhow = "1"
Expand All @@ -21,6 +22,7 @@ tokio = { version = "1", features = ["sync", "fs", "time", "io-util", "macros",
toml = "1.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tracing = { version = "0.1", features = ["log"] }
codspeed-criterion-compat = { version = "5.0.1", optional = true }

[dev-dependencies]
criterion = "0.8"
Expand Down
2 changes: 2 additions & 0 deletions crates/ironrdp-bench/benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
use core::hint::black_box;
use core::num::{NonZeroU16, NonZeroUsize};

#[cfg(feature = "codspeed")]
use codspeed_criterion_compat as criterion;
use criterion::{Criterion, criterion_group, criterion_main};
use ironrdp_graphics::color_conversion::to_64x64_ycbcr_tile;
use ironrdp_pdu::codecs::rfx;
Expand Down
2 changes: 2 additions & 0 deletions crates/ironrdp-bench/benches/capture_replay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

use core::hint::black_box;

#[cfg(feature = "codspeed")]
use codspeed_criterion_compat as criterion;
use criterion::{Criterion, criterion_group, criterion_main};
use ironrdp_bench::connector_replay::{ConnectorReplayId, ConnectorReplayWorkload};
use ironrdp_bench::replay::{PartialReplayId, PartialReplayWorkload};
Expand Down
33 changes: 33 additions & 0 deletions xtask/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,38 @@ hyperfine --warmup 1 '.\target\release\capture-replay-bench.exe --connector no-n
```
Use `cargo xtask bench replay` to regression-test the complete pinned corpus, not to produce a single-capture timing score.

## CodSpeed reporting

CodSpeed simulation measures the three individually named encoder workloads (`rfx_enc_tile`, `rfx_enc`, and `to_ycbcr`) plus the two passive partial replays and one connector replay.
The simulation job fetches and verifies the corpus before benchmark setup, then each replay target prepares and strictly preflights its selected capture outside Criterion's timed iterations.
Every timed iteration starts with fresh replay, connector, and session state.
CPU simulation models deterministic user-space work and is useful for focused processing regressions, not wall-clock completion, hardware-specific SIMD behavior, or native H.264 performance.

The `codspeed` feature selects `codspeed-criterion-compat` only for the two benchmark targets.
Regular `cargo bench` continues to use Criterion 0.8.
Build the CodSpeed targets locally without uploading results with:

```PowerShell
cargo xtask bench corpus-fetch
cargo install cargo-codspeed --version 5.0.1 --locked
cargo codspeed build -p ironrdp-bench --bench bench --bench capture_replay --features codspeed --locked -m simulation
```

Use the local Criterion and Hyperfine commands above; replace `no-nla-accepted` with `no-nla-smartcard` in the Criterion filter to benchmark that passive replay.

Hyperfine remains a separate local tool and does not import results into CodSpeed.

`codspeed.yml` defines the independent wall-time command identities `exec_harness::partial-replay/no-nla-accepted/strict-cli`, `exec_harness::partial-replay/no-nla-smartcard/strict-cli`, and `exec_harness::connector-replay/no-nla-accepted/strict-cli`.
Each command starts one release binary process, verifies and loads the selected cached capture, decrypts and prepares its replay state, and executes one strict replay.
Compilation and corpus fetching occur before the CodSpeed action and are excluded from this measurement.

The `CodSpeed` workflow runs simulation for pushes, pull requests, and manual dispatches after maintainers set the `CODSPEED_ENABLED` repository variable to `true` and enable the repository in CodSpeed.
It authenticates through GitHub OIDC and requires no repository secret for this public repository.
The wall-time job is manual only and runs only when `CODSPEED_ENABLED` is `true` and maintainers set the repository-controlled `CODSPEED_WALLTIME_RUNNER` variable to a known, approved Linux runner label.
Dispatchers cannot select or override the wall-time runner.
Use a dedicated stable runner for wall time; shared hosted runners are too noisy for performance decisions.
The public capture cache uses the existing manifest-hash cache key and is digest-verified before use.
Do not upload captures, decrypted payloads, TLS key material, screenshots, or generated replay output; CodSpeed receives measurements and may retain symbol-bearing profiles, not raw replay payloads.

To update the corpus, inspect the upstream capture inventory, revise the manifest revision, inventory, scenario intent metadata, replay expectations, and SHA-256 digests together, then run `cargo xtask bench corpus-fetch` followed by `cargo xtask bench replay`.
Do not commit captures, TLS key material, decrypted payloads, screenshots, or generated output.
Loading