Skip to content

bench: size-only encoding benchmark and wire-size sweeps - #136

Merged
Thecave3 merged 2 commits into
mainfrom
bench/encoding-wire-size
Nov 3, 2026
Merged

Thecave3 merged 2 commits into
mainfrom
bench/encoding-wire-size

Conversation

@Thecave3

@Thecave3 Thecave3 commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • test_bench_encoding_size gains --sizes-only (no timing; each PDU is decoded and re-encoded and a byte mismatch is reported) and --no-timestamp (leaves the optional E3-PDU envelope timestamp off the wire). Its DAppReport and XAppControlAction samples now set sequence_id = 1: the field is mandatory with range 1..4294967295, and the zero sample made the APER encoder fail on both.
  • New test_bench_encoding_wire measures sizes only, one mode per run: --payload (wire size against opaque payload size), --values (min/typical/max per PDU and one-parameter sweeps over ids, id-list lengths, RAN function count and optional-field presence), --fields (APER cost per field group by differential encoding), --e2sm (E2SM-DAPP element sizes around an E3 payload, and the size of each golden vector) and --dump (the encoded PDUs, for offline parsing and compression). No sockets and no timing.
  • PDUs an encoder rejects are written as NA. This shows that the APER encoder cannot encode a PDU larger than its fixed 65,536-byte output buffer (for example a SetupResponse with 60 or more functions of 256 + 256 ids, or ranFunctionData of about 65,500 bytes), while protobuf and JSON can. That limit is not changed here and will be filed separately.

Type of change

  • Test / CI / packaging

Twin-repo coordination

  • This PR does not change the E3 wire protocol or public ABI, OR a paired PR exists in each affected twin repo (link below).
  • This PR does not change the wire format or a behavior a peer (OAI, Aerial, OCUDU) can observe, OR I added a row to the change ledger in docs/interop.md.

Paired PR(s): none, tests and CMake only.

Local checks

  • Branch is on top of origin/main (af98e5c), linear, no merge commits.
  • Clean Release build with ASN.1, JSON, protobuf, tests, integration tests and examples on, in libe3-dev:24.04 (aarch64): ctest passes 43/43, including test_bench_encoding_wire (runs --values) and test_bench_encoding_size. The build was made on 75c4e1c; the one commit since then only changes .github/scripts/detect_code_changes.sh.
  • python3 scripts/check_commit_trailers.py --base origin/main --head HEAD passes.
  • Not run: the Debug build, the MPMC benchmark, an independent per-commit build of the first commit, and the Docs check (no documentation input is touched).

--sizes-only skips the timing run and prints the four size columns, after
checking that each PDU decodes and re-encodes to the same bytes.
--no-timestamp zeroes Pdu::timestamp so the optional E3-PDU envelope
timestamp stays off the wire.

DAppReport and XAppControlAction samples now set sequence_id = 1: the
field is mandatory with range 1..4294967295, and the zero sample made the
APER encoder fail on both. It is counted in info_bytes.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Thecave3 <thecave003@gmail.com>
test_bench_encoding_wire measures sizes only, one mode per run: payload
size sweep, min/typical/max and one-parameter value sweeps, APER
differential field costs, the sizes of the E2SM-DAPP elements built from
the golden fixtures, and a dump of the encoded PDUs for offline parsing and
compression. Every PDU is decoded and re-encoded and a byte mismatch is
reported. PDUs the encoder rejects are written as NA.

It links libe3::e2sm_dapp when that target exists.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Thecave3 <thecave003@gmail.com>
@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

CI report — 6d97ab4 — ✅ all checks passed

Workflow Result Time Run
Build libe3py wheels ✅ success 13m10s #42
Commit policy ✅ success 3m31s #207
Docs ✅ success 0m36s #14
E2E dApp Integration ✅ success 5m30s #196
E2E Topologies (multi-dApp / multi-RAN) ✅ success 3m38s #194
Full-loop Latency Benchmark ✅ success 2m12s #195
Unit Tests ✅ success 6m49s #222
latrec portability ⏭️ not triggered (paths filter) — —
MPMC Queue Benchmark ⏭️ not triggered (paths filter) — —
E2E Topologies (multi-dApp / multi-RAN)

zmq/ipc

  • ✅ 1 RAN - 1 dApp: indications=5
    • dapp peer=t11 ran=ran-solo sub=1 indications=5 seq=[0..4] dropped=0 (0%) age_ms(avg=0 max=0 @seq=0) hist[<=1:5 2-5:0 6-10:0 >10:0]
  • ✅ 1 RAN - 2 dApps: dApp#1 ind=5 sub=1, dApp#2 ind=6 sub=2, RAN saw 2 dApps
    • dapp1 peer=t12 ran=ran-shared sub=1 indications=5 seq=[0..4] dropped=0 (0%) age_ms(avg=0.2 max=1 @seq=0) hist[<=1:5 2-5:0 6-10:0 >10:0]
    • dapp2 peer=t12 ran=ran-shared sub=2 indications=6 seq=[0..5] dropped=0 (0%) age_ms(avg=0.166667 max=1 @seq=0) hist[<=1:6 2-5:0 6-10:0 >10:0]
  • ✅ 2 RANs - 1 dApp: from ran-a ind=5, from ran-b ind=5
    • dapp peer=t2a ran=ran-a sub=1 indications=5 seq=[0..4] dropped=0 (0%) age_ms(avg=0.6 max=1 @seq=0) hist[<=1:5 2-5:0 6-10:0 >10:0]
    • dapp peer=t2b ran=ran-b sub=1 indications=5 seq=[0..4] dropped=0 (0%) age_ms(avg=0 max=0 @seq=0) hist[<=1:5 2-5:0 6-10:0 >10:0]

zmq/tcp

  • ✅ 1 RAN - 1 dApp: indications=5
    • dapp peer=default ran=ran-solo sub=1 indications=5 seq=[0..4] dropped=0 (0%) age_ms(avg=0.2 max=1 @seq=0) hist[<=1:5 2-5:0 6-10:0 >10:0]
  • ✅ 1 RAN - 2 dApps: dApp#1 ind=5 sub=1, dApp#2 ind=6 sub=2, RAN saw 2 dApps
    • dapp1 peer=default ran=ran-shared sub=1 indications=5 seq=[0..4] dropped=0 (0%) age_ms(avg=0.8 max=1 @seq=1) hist[<=1:5 2-5:0 6-10:0 >10:0]
    • dapp2 peer=default ran=ran-shared sub=2 indications=6 seq=[0..5] dropped=0 (0%) age_ms(avg=0.833333 max=1 @seq=1) hist[<=1:6 2-5:0 6-10:0 >10:0]
  • ✅ 2 RANs - 1 dApp: from ran-a ind=5, from ran-b ind=5
    • dapp peer=default ran=ran-a sub=1 indications=5 seq=[0..4] dropped=0 (0%) age_ms(avg=0 max=0 @seq=0) hist[<=1:5 2-5:0 6-10:0 >10:0]
    • dapp peer=off100 ran=ran-b sub=1 indications=5 seq=[0..4] dropped=0 (0%) age_ms(avg=0.8 max=1 @seq=1) hist[<=1:5 2-5:0 6-10:0 >10:0]
E2E dApp Integration

✅ posix/ipc

  • dApp exit: 0
  • Indications received: 7

✅ posix/tcp

  • dApp exit: 0
  • Indications received: 7

✅ zmq/ipc

  • dApp exit: 0
  • Indications received: 7

✅ zmq/tcp

  • dApp exit: 0
  • Indications received: 7
Full-loop Latency Benchmark

Full-loop latency

Full-loop latency benchmark (N=1051 after 50 warmup)

All values in microseconds (μs). Link: zmq, transport: ipc, encoding: ASN.1 APER.

# Description Tags mean p50 p99 max
1 Collect indication data RECORD_BEGIN to ENCODE_E3SM_BEGIN 0.19 0.09 0.21 13.47
2 Create & encode indication ENCODE_E3SM_BEGIN to ENCODE_E3SM_DONE 0.85 0.53 13.28 30.25
3 Encode E3AP (indication) EMIT_ENTER to ENQUEUE, then DEQUEUE to ENCODE_E3AP_DONE 2.41 1.97 13.57 16.73
4 Queuing (indication) ENQUEUE to DEQUEUE 6.47 4.15 21.68 43.73
5 Delivery (indication) ENCODE_E3AP_DONE to SEND_DONE 0.92 0.37 10.78 18.21
6 E3 wire (RAN -> dApp) SEND_DONE to RECV 40.54 38.01 69.87 526.46
7 Decode E3AP (indication) RECV to DECODE_E3AP_DONE 1.30 0.93 10.28 14.95
8 libe3 dispatch (indication) DECODE_E3AP_DONE to DELIVER_BEGIN 0.13 0.07 0.27 21.81
9 Decode indication DELIVER_BEGIN to DECODE_E3SM_DONE 0.30 0.25 0.58 13.52
10 Process data DECODE_E3SM_DONE to ENCODE_E3SM_BEGIN 0.03 0.02 0.05 5.16
11 Create & encode control ENCODE_E3SM_BEGIN to ENCODE_E3SM_DONE 0.21 0.18 0.42 13.32
12 Encode E3AP (control) EMIT_ENTER to ENQUEUE, then DEQUEUE to ENCODE_E3AP_DONE 1.98 1.72 9.56 24.68
13 Queuing (control) ENQUEUE to DEQUEUE 10.67 9.48 23.46 31.51
14 Delivery (control) ENCODE_E3AP_DONE to SEND_DONE 5.50 3.87 17.75 24.79
15 E3 wire (dApp -> RAN) SEND_DONE to RECV 36.96 36.18 61.56 191.52
16 Decode E3AP (control) RECV to DECODE_E3AP_DONE 2.06 1.43 14.77 19.39
17 libe3 dispatch (control) DECODE_E3AP_DONE to DECODE_E3SM_BEGIN 0.31 0.21 0.61 18.10
18 Decode & handle control DECODE_E3SM_BEGIN to DECODE_E3SM_DONE 0.17 0.16 0.39 0.61
Total Total round-trip 111.62 109.13 152.99 815.09

ubuntu-latest, Release build, ZMQ + IPC, ASN.1 APER.

These numbers are measured inside a GitHub Actions container and should be treated as an upper bound on E3AP's and the library's own latency, not a representative deployment measurement.

Ready to merge (fast-forward only)

A maintainer can land the reviewed commits with:

git fetch origin
git checkout main && git merge --ff-only 6d97ab44932d094916cb7083105b1a282609a808 && git push origin main

Head: 6d97ab44932d094916cb7083105b1a282609a808 (branch bench/encoding-wire-size). If --ff-only fails as non-fast-forward, the branch must be rebased on the latest main.

One comment per PR, rewritten in place once every workflow for 6d97ab4 finished.

@Thecave3
Thecave3 merged commit 6d97ab4 into main Nov 3, 2026
31 checks passed
@Thecave3
Thecave3 deleted the bench/encoding-wire-size branch November 3, 2026 19:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant