Skip to content

Commit 5111bc3

Browse files
perf(wchar): add 4-byte wcstombs SIMD encode (bd-w7mtzu)
Same-worker RCH vmi1153651 Criterion wchar_wcstombs/astral_4byte improved from [16.014 us 17.148 us 18.625 us] to [918.85 ns 997.60 ns 1.0930 us] for 1024 astral codepoints, 17.19x faster by middle estimate. Proof: local and RCH vmi1153651 core scalar-isomorphism, live-glibc conformance_diff_wcstombs_simd, and golden_wchar_conv_reentry passed with unchanged wide SHA e52563fe0c036cc2d97d9b14a28d8d0e3adeec307686eecf8122466ca95dab50 and byte SHA 5f71c2382d1655e56994e4022f3e88be237d22350f6af9bd744680ec108aad6e. Touched-file rustfmt, crate-scoped checks, and git diff --check passed. Focused clippy remains blocked by pre-existing exp/sort/fnmatch/regex lint debt outside this change.
1 parent 4f52803 commit 5111bc3

5 files changed

Lines changed: 260 additions & 15 deletions

File tree

.skill-loop-progress.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,3 +781,13 @@
781781
- Same-worker post: `wchar_wcstombs/cjk_3byte` improved to `[966.19 ns 1.0170 us 1.0763 us]`, throughput `[951.44 Melem/s 1.0069 Gelem/s 1.0598 Gelem/s]`. Middle estimate improved `11.849 us -> 1.0170 us` (`11.65x` faster), or `11.571 ns/wc -> 0.993 ns/wc`.
782782
- Verdict: KEPT, Score `(Impact 5.0 x Confidence 5.0) / Effort 2.0 = 12.5`. Artifact: `tests/artifacts/perf/bd-w7mtzu-wcstombs-3byte-simd.md`.
783783
- Remaining route on `bd-w7mtzu`: 4-byte astral paths remain open; do not call the bead fully closed until that lane is separately profiled and addressed.
784+
785+
### Pass 85 - Wcstombs 4-byte UTF-8 Packed SIMD Encode - 2026-06-13T09:08:00Z
786+
- Target: `bd-w7mtzu` / `wcstombs` pure 4-byte astral/RFC2279 encode, selected after adding focused astral Criterion rows and measuring both directions on same-worker RCH.
787+
- Focused same-worker baseline: RCH `vmi1153651` `wchar_mbstowcs/astral_4byte` `[11.407 us 12.128 us 12.874 us]`; `wchar_wcstombs/astral_4byte` `[16.014 us 17.148 us 18.625 us]` for 1024 codepoints, making encode the larger scalar residual.
788+
- One retained lever: add a four-wide packed byte-lane SIMD encoder for scalar `wctomb`'s existing RFC 2279 4-byte branch (`0x1_0000..0x20_0000`). It computes lead/continuation lanes, packs them with `simd_swizzle!` into one `u8x16`, and writes a 16-byte window. ASCII, 2/3-byte, 5/6-byte, invalid, NUL, mixed-window, and short-output cases fall back to scalar `wctomb`.
789+
- Behavior proof: local and RCH `vmi1153651` core scalar-isomorphism passed with new deterministic 4-byte windows; local and RCH `vmi1153651` live-glibc `conformance_diff_wcstombs_simd` passed after extending to 2/3/4-byte-heavy fuzz; local and RCH `vmi1153651` golden `golden_wchar_conv_reentry` passed with unchanged wide SHA `e52563fe0c036cc2d97d9b14a28d8d0e3adeec307686eecf8122466ca95dab50` and round-trip byte SHA `5f71c2382d1655e56994e4022f3e88be237d22350f6af9bd744680ec108aad6e`.
790+
- Validation notes: touched-file `rustfmt --check`, local crate-scoped checks, and `git diff --check` passed. Focused clippy remains blocked by pre-existing lint debt in `math/exp.rs`, `stdlib/sort.rs`, `string/fnmatch.rs`, and `string/regex.rs`; no reported clippy error is in this pass's touched files.
791+
- Same-worker post: `wchar_wcstombs/astral_4byte` improved to `[918.85 ns 997.60 ns 1.0930 us]`, throughput `[936.85 Melem/s 1.0265 Gelem/s 1.1144 Gelem/s]`. Middle estimate improved `17.148 us -> 997.60 ns` (`17.19x` faster), or `16.746 ns/wc -> 0.974 ns/wc`.
792+
- Verdict: KEPT, Score `(Impact 5.0 x Confidence 5.0) / Effort 2.0 = 12.5`. Artifact: `tests/artifacts/perf/bd-w7mtzu-wchar-4byte-simd.md`.
793+
- Remaining route on `bd-w7mtzu`: 4-byte `mbstowcs` decode remains open and still needs its own profile/proof loop.

crates/frankenlibc-abi/tests/conformance_diff_wcstombs_simd.rs

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
#![cfg(target_os = "linux")]
22
#![allow(unsafe_code)] // live host-glibc wcstombs oracle
33

4-
//! Differential fuzz for the SIMD 2-byte and 3-byte UTF-8 *encode* fast paths in
4+
//! Differential fuzz for the SIMD 2-byte, 3-byte, and 4-byte UTF-8 *encode* fast paths in
55
//! `frankenlibc_core::string::wchar::wcstombs` (bd-w7mtzu).
66
//!
77
//! The fast path encodes runs of >= 8 wide chars all in 0x80..=0x7FF — each to
88
//! exactly two UTF-8 bytes — 8 chars per 16-byte vector. It must be byte-for-byte
99
//! identical to scalar `wctomb`. The 3-byte path does the same for clean BMP
1010
//! non-surrogate runs in 0x0800..=0xFFFF, four wide chars per 12 output bytes.
11-
//! This fuzzes 2/3-byte-heavy wide-char arrays (interleaved with ASCII, 4-byte
12-
//! code points, surrogates, out-of-range values, and runs straddling both SIMD
13-
//! window sizes) against the LIVE host glibc `wcstombs` oracle (C.UTF-8),
14-
//! comparing the full byte output and the success/error decision on every case.
11+
//! The 4-byte path covers scalar `wctomb`'s RFC 2279 branch
12+
//! 0x1_0000..0x20_0000, four wide chars per 16 output bytes. This fuzzes
13+
//! 2/3/4-byte-heavy wide-char arrays (interleaved with ASCII, 5/6-byte code
14+
//! points, surrogates, out-of-range values, and runs straddling all SIMD window
15+
//! sizes) against the LIVE host glibc `wcstombs` oracle (C.UTF-8), comparing the
16+
//! full byte output and the success/error decision on every case.
1517
1618
use std::ffi::c_char;
1719

@@ -36,7 +38,7 @@ impl Lcg {
3638

3739
fn glibc_wcstombs(src: &[i32]) -> Option<Vec<u8>> {
3840
// src must be NUL-terminated (a 0 wchar) for glibc.
39-
let mut dst = vec![0i8; src.len() * 4 + 4];
41+
let mut dst = vec![0i8; src.len() * 6 + 6];
4042
let n = unsafe { wcstombs(dst.as_mut_ptr(), src.as_ptr(), dst.len()) };
4143
if n == usize::MAX {
4244
None
@@ -48,7 +50,7 @@ fn glibc_wcstombs(src: &[i32]) -> Option<Vec<u8>> {
4850
fn fl_wcstombs(src: &[i32]) -> Option<Vec<u8>> {
4951
let nul = src.iter().position(|&w| w == 0).unwrap_or(src.len());
5052
let su: Vec<u32> = src[..nul].iter().map(|&w| w as u32).collect();
51-
let mut dst = vec![0u8; src.len() * 4 + 4];
53+
let mut dst = vec![0u8; src.len() * 6 + 6];
5254
frankenlibc_core::string::wchar::wcstombs(&mut dst, &su).map(|n| dst[..n].to_vec())
5355
}
5456

@@ -62,8 +64,18 @@ fn valid_3byte_codepoint(r: &mut Lcg) -> i32 {
6264
}
6365
}
6466

67+
fn valid_4byte_codepoint(r: &mut Lcg) -> i32 {
68+
match r.below(5) {
69+
0 => 0x1_0000 + r.below(0x1000) as i32,
70+
1 => 0x1F600 + r.below(0x80) as i32,
71+
2 => 0x10_FFFF,
72+
3 => 0x11_0000 + r.below(0x1000) as i32,
73+
_ => 0x1F_FFFF,
74+
}
75+
}
76+
6577
#[test]
66-
fn wcstombs_simd_2byte_and_3byte_matches_glibc() {
78+
fn wcstombs_simd_2byte_3byte_and_4byte_matches_glibc() {
6779
unsafe {
6880
setlocale(6 /*LC_ALL*/, b"C.UTF-8\0".as_ptr() as *const c_char)
6981
};
@@ -76,7 +88,7 @@ fn wcstombs_simd_2byte_and_3byte_matches_glibc() {
7688
let mut s: Vec<i32> = Vec::new();
7789
let segs = r.below(20);
7890
for _ in 0..segs {
79-
match r.below(10) {
91+
match r.below(12) {
8092
// Bias toward 2-byte code points (the SIMD path), in runs.
8193
0..=3 => {
8294
let run = 1 + r.below(12);
@@ -91,17 +103,23 @@ fn wcstombs_simd_2byte_and_3byte_matches_glibc() {
91103
s.push(valid_3byte_codepoint(&mut r));
92104
}
93105
}
94-
8 => {
106+
// Bias toward valid 4-byte code points, in runs.
107+
8..=9 => {
108+
let run = 1 + r.below(12);
109+
for _ in 0..run {
110+
s.push(valid_4byte_codepoint(&mut r));
111+
}
112+
}
113+
10 => {
95114
for _ in 0..(1 + r.below(10)) {
96115
s.push((1 + r.below(0x7F)) as i32); // ASCII
97116
}
98117
}
99-
9 if r.below(2) == 0 => s.push((0x1_0000 + r.below(0x10_0000)) as i32), // 4-byte astral
100118
_ => {
101-
// Edge values: surrogates / out-of-range (glibc & fl both error).
119+
// Edge values: surrogates / 5-6-byte / out-of-range.
102120
match r.below(3) {
103121
0 => s.push((0xD800 + r.below(0x800)) as i32), // surrogate
104-
1 => s.push(0x11_0000 + r.below(0x1000) as i32), // > U+10FFFF
122+
1 => s.push(0x20_0000 + r.below(0x1000) as i32), // 5-byte branch
105123
_ => s.push((0x80 + r.below(0x780)) as i32),
106124
}
107125
}
@@ -124,7 +142,7 @@ fn wcstombs_simd_2byte_and_3byte_matches_glibc() {
124142

125143
assert!(
126144
divs.is_empty(),
127-
"wcstombs SIMD 2-byte path diverged from glibc on some of {compared} cases (up to 20):\n{}",
145+
"wcstombs SIMD encode paths diverged from glibc on some of {compared} cases (up to 20):\n{}",
128146
divs.join("\n")
129147
);
130148
}

crates/frankenlibc-bench/benches/wchar_bench.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,22 @@ fn bench_mbstowcs(c: &mut Criterion) {
2525
}
2626
mixed.push(b' ');
2727
}
28+
// Pure 4-byte astral codepoints. This isolates the remaining scalar
29+
// multibyte decode lane after 2-byte and 3-byte SIMD windows landed.
30+
let mut astral_4byte: Vec<u8> = Vec::with_capacity(1024 * 4);
31+
for i in 0..1024 {
32+
let cp = 0x1F600 + (i % 0x80) as u32;
33+
astral_4byte.push(0xF0 | (cp >> 18) as u8);
34+
astral_4byte.push(0x80 | ((cp >> 12) & 0x3F) as u8);
35+
astral_4byte.push(0x80 | ((cp >> 6) & 0x3F) as u8);
36+
astral_4byte.push(0x80 | (cp & 0x3F) as u8);
37+
}
2838

29-
let cases: &[(&str, &[u8])] = &[("ascii_1k", &ascii), ("mixed_utf8", &mixed)];
39+
let cases: &[(&str, &[u8])] = &[
40+
("ascii_1k", &ascii),
41+
("astral_4byte", &astral_4byte),
42+
("mixed_utf8", &mixed),
43+
];
3044

3145
let mut group = c.benchmark_group("wchar_mbstowcs");
3246
for &(name, src) in cases {
@@ -48,6 +62,9 @@ fn bench_wcstombs(c: &mut Criterion) {
4862
// Pure 3-byte BMP codepoints. This is the remaining multibyte encode lane
4963
// after the 2-byte SIMD path landed.
5064
let cjk_3byte: Vec<u32> = (0..1024).map(|i| 0x4E00 + (i % 0x100) as u32).collect();
65+
// Pure 4-byte astral codepoints. This isolates the remaining scalar
66+
// multibyte encode lane after 2-byte and 3-byte SIMD windows landed.
67+
let astral_4byte: Vec<u32> = (0..1024).map(|i| 0x1F600 + (i % 0x80) as u32).collect();
5168
// Mixed: ASCII runs interleaved with 2/3-byte codepoints.
5269
let mut mixed: Vec<u32> = Vec::new();
5370
for i in 0..128 {
@@ -58,6 +75,7 @@ fn bench_wcstombs(c: &mut Criterion) {
5875

5976
let cases: &[(&str, &[u32])] = &[
6077
("ascii_1k", &ascii),
78+
("astral_4byte", &astral_4byte),
6179
("cjk_3byte", &cjk_3byte),
6280
("mixed_utf8", &mixed),
6381
];

crates/frankenlibc-core/src/string/wchar.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,39 @@ pub fn wcstombs(dest: &mut [u8], src: &[u32]) -> Option<usize> {
592592
di += 12;
593593
}
594594

595+
// SIMD 4-byte encode fast path for scalar wctomb's RFC 2279 4-byte
596+
// branch. Each clean window maps four code points in
597+
// 0x1_0000..0x20_0000 to exactly sixteen output bytes. ASCII, 2/3-byte,
598+
// 5/6-byte, invalid, NUL, mixed-window, and short-output cases fall
599+
// through to scalar `wctomb`, preserving glibc-compatible semantics.
600+
while si + 4 <= src.len()
601+
&& di + 16 <= dest.len()
602+
&& (0x1_0000..0x20_0000).contains(&src[si])
603+
{
604+
let ws: [u32; 4] = src[si..si + 4].try_into().unwrap();
605+
let v = Simd::<u32, 4>::from_array(ws);
606+
if !(v.simd_ge(Simd::splat(0x1_0000)) & v.simd_lt(Simd::splat(0x20_0000))).all() {
607+
break;
608+
}
609+
610+
let leads = ((v >> Simd::splat(18)) | Simd::splat(0xF0)).cast::<u8>();
611+
let cont1 =
612+
(((v >> Simd::splat(12)) & Simd::splat(0x3F)) | Simd::splat(0x80)).cast::<u8>();
613+
let cont2 =
614+
(((v >> Simd::splat(6)) & Simd::splat(0x3F)) | Simd::splat(0x80)).cast::<u8>();
615+
let cont3 = ((v & Simd::splat(0x3F)) | Simd::splat(0x80)).cast::<u8>();
616+
let lead_cont1 = std::simd::simd_swizzle!(leads, cont1, [0, 4, 1, 5, 2, 6, 3, 7]);
617+
let cont2_cont3 = std::simd::simd_swizzle!(cont2, cont3, [0, 4, 1, 5, 2, 6, 3, 7]);
618+
let bytes = std::simd::simd_swizzle!(
619+
lead_cont1,
620+
cont2_cont3,
621+
[0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15]
622+
);
623+
bytes.copy_to_slice(&mut dest[di..di + 16]);
624+
si += 4;
625+
di += 16;
626+
}
627+
595628
// One scalar step, then re-attempt the SIMD run.
596629
if si >= src.len() {
597630
return Some(di);
@@ -819,6 +852,22 @@ mod tests {
819852
}
820853
corpus.push(v);
821854
}
855+
// Pure 4-byte runs around the 4-codepoint SIMD window. The upper cases
856+
// intentionally cover scalar wctomb's glibc-compatible RFC 2279 range,
857+
// not just Unicode scalar values through U+10FFFF.
858+
for len in 0..40usize {
859+
let mut v = Vec::with_capacity(len);
860+
for i in 0..len {
861+
v.push(match i % 5 {
862+
0 => 0x1_0000,
863+
1 => 0x1F600 + (i as u32 % 0x80),
864+
2 => 0x10_FFFF,
865+
3 => 0x11_0000 + (i as u32 % 0x100),
866+
_ => 0x1F_FFFF,
867+
});
868+
}
869+
corpus.push(v);
870+
}
822871
// Surrogates / out-of-range values wctomb rejects (must bail to scalar
823872
// and return None identically).
824873
corpus.push(vec![0x78, 0x79, 0xD800, 0x7A]);
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# bd-w7mtzu - wcstombs 4-byte packed SIMD encode keep
2+
3+
Date: 2026-06-13
4+
Agent: BoldFalcon
5+
Bead: `bd-w7mtzu`
6+
Lever: packed four-wide UTF-8 4-byte encode window in `wcstombs`
7+
Verdict: KEPT
8+
Score: `(Impact 5.0 x Confidence 5.0) / Effort 2.0 = 12.5`
9+
10+
## Target
11+
12+
After the retained 2-byte, 3-byte decode, and 3-byte encode windows, the
13+
remaining profiled wchar residual was the astral 4-byte lane. A focused
14+
Criterion row was added before the production edit for both directions:
15+
16+
- `wchar_mbstowcs/astral_4byte`
17+
- `wchar_wcstombs/astral_4byte`
18+
19+
The baseline selected encode as the next lever: `wcstombs/astral_4byte`
20+
was slower than decode and still scalar per codepoint.
21+
22+
## Recommendation Contract
23+
24+
- Change: add a fixed-width packed byte-lane SIMD encoder for scalar
25+
`wctomb`'s RFC 2279 4-byte branch.
26+
- Failure signature evidence: same-worker `vmi1153651` Criterion baseline
27+
showed `wchar_wcstombs/astral_4byte` middle `17.148 us` for 1024 codepoints.
28+
- Mapped primitive: SIMD batching plus explicit UTF-8 state/range automaton.
29+
- EV score: `(Impact 5 x Confidence 5 x Reuse 2) / (Effort 2 x Friction 1) = 25`.
30+
- Relevance score: 5.0, directly targets the measured scalar hot lane.
31+
- Primary risk: accepting or rejecting a different codepoint set than scalar
32+
`wctomb`. Countermeasure: SIMD path is gated to `0x1_0000..0x20_0000`, the
33+
exact scalar 4-byte branch, with all other values falling back to scalar.
34+
- Budgeted mode: one fixed 4-codepoint window per iteration; no adaptive state.
35+
- Fallback trigger: any mixed-width, NUL, short-output, 2/3-byte, 5/6-byte, or
36+
invalid window breaks to the scalar `wctomb` step.
37+
- Baseline comparator: same-worker Criterion baseline on `vmi1153651`.
38+
- Rollback: revert the single commit that adds the 4-byte encode window.
39+
- Verification artifacts: core scalar-isomorphism, live-glibc differential,
40+
golden SHA reentry, same-worker Criterion before/after, touched-file rustfmt,
41+
`git diff --check`.
42+
43+
## Baseline
44+
45+
RCH command:
46+
47+
```text
48+
env RCH_REQUIRE_REMOTE=1 RCH_WORKER=vmi1153651 RCH_VISIBILITY=summary \
49+
RCH_QUEUE_WHEN_BUSY=1 RCH_DAEMON_WAIT_RESPONSE_TIMEOUT_SECS=900 rch exec -- \
50+
env AGENT_NAME=BoldFalcon FRANKENLIBC_BENCH_PIN=1 CARGO_BUILD_JOBS=1 \
51+
cargo bench -j 1 -p frankenlibc-bench --bench wchar_bench -- \
52+
astral_4byte --noplot --sample-size 60 --warm-up-time 1 --measurement-time 3
53+
```
54+
55+
Baseline on `vmi1153651`:
56+
57+
```text
58+
wchar_mbstowcs/astral_4byte
59+
[11.407 us 12.128 us 12.874 us]
60+
[303.43 MiB/s 322.09 MiB/s 342.45 MiB/s]
61+
62+
wchar_wcstombs/astral_4byte
63+
[16.014 us 17.148 us 18.625 us]
64+
[54.981 Melem/s 59.715 Melem/s 63.942 Melem/s]
65+
```
66+
67+
## Change
68+
69+
`wcstombs` now has a 4-codepoint SIMD encode window after the 3-byte path:
70+
71+
- Range gate: all four `u32` codepoints must be in `0x1_0000..0x20_0000`.
72+
- Byte lanes:
73+
- `0xF0 | (wc >> 18)`
74+
- `0x80 | ((wc >> 12) & 0x3F)`
75+
- `0x80 | ((wc >> 6) & 0x3F)`
76+
- `0x80 | (wc & 0x3F)`
77+
- Packing: `simd_swizzle!` interleaves the four byte lanes into one `u8x16`.
78+
- Store: one `copy_to_slice` writes the 16-byte window.
79+
80+
This is one lever: it does not change 4-byte decode, ASCII, 2-byte, 3-byte,
81+
5/6-byte, invalid, NUL, or short-output scalar behavior.
82+
83+
## Isomorphism
84+
85+
- Ordering preserved: output byte triples/quads are packed in source order.
86+
- Tie-breaking unchanged: not applicable.
87+
- Floating point: not involved.
88+
- RNG seeds: unchanged/not involved.
89+
- Error behavior: unchanged. The SIMD path fires only for scalar `wctomb`'s
90+
existing 4-byte branch. Surrogates, out-of-range values, 5/6-byte values,
91+
NULs, mixed-width windows, and insufficient output capacity use scalar
92+
`wctomb`.
93+
- Truncation behavior: unchanged. The SIMD path requires 16 output bytes before
94+
firing; otherwise scalar handles exact remaining capacity.
95+
96+
## Proof
97+
98+
Local:
99+
100+
- `cargo test -j 1 -p frankenlibc-core --lib wcstombs_simd_isomorphic_to_scalar -- --nocapture --test-threads=1`: passed.
101+
- `cargo test -j 1 -p frankenlibc-abi --test conformance_diff_wcstombs_simd -- --nocapture --test-threads=1`: passed.
102+
- `cargo test -j 1 -p frankenlibc-abi --test golden_wchar_conv_reentry -- --nocapture --test-threads=1`: passed.
103+
- `rustfmt --check crates/frankenlibc-core/src/string/wchar.rs crates/frankenlibc-abi/tests/conformance_diff_wcstombs_simd.rs crates/frankenlibc-bench/benches/wchar_bench.rs`: passed.
104+
- `cargo check -j 1 -p frankenlibc-core --lib`: passed.
105+
- `cargo check -j 1 -p frankenlibc-abi --test conformance_diff_wcstombs_simd`: passed with the existing `wchar_abi.rs` `work_local` unused-assignment warning.
106+
- `cargo check -j 1 -p frankenlibc-bench --bench wchar_bench`: passed.
107+
- `git diff --check`: passed.
108+
109+
RCH `vmi1153651`:
110+
111+
- `cargo test -j 1 -p frankenlibc-core --lib wcstombs_simd_isomorphic_to_scalar -- --nocapture --test-threads=1`: passed.
112+
- `cargo test -j 1 -p frankenlibc-abi --test conformance_diff_wcstombs_simd -- --nocapture --test-threads=1`: passed.
113+
- `cargo test -j 1 -p frankenlibc-abi --test golden_wchar_conv_reentry -- --nocapture --test-threads=1`: passed.
114+
- Golden SHA: `mbstowcs wide sha256=e52563fe0c036cc2d97d9b14a28d8d0e3adeec307686eecf8122466ca95dab50`.
115+
- Golden SHA: `wcstombs back sha256=5f71c2382d1655e56994e4022f3e88be237d22350f6af9bd744680ec108aad6e`.
116+
117+
Known environment noise:
118+
119+
- RCH and local builds report the existing missing SMT solver warning.
120+
- ABI builds report the existing `wchar_abi.rs` `work_local` unused-assignment warning.
121+
- Focused `cargo clippy -j 1 -p frankenlibc-core --lib -- -D warnings`
122+
remains blocked by pre-existing lint debt in `math/exp.rs`, `stdlib/sort.rs`,
123+
`string/fnmatch.rs`, and `string/regex.rs`. No reported clippy error was in
124+
this pass's touched wchar encoder/test/bench files.
125+
126+
## Post
127+
128+
Same-worker RCH post on `vmi1153651`, same command:
129+
130+
```text
131+
wchar_mbstowcs/astral_4byte
132+
[10.735 us 10.994 us 11.304 us]
133+
[345.56 MiB/s 355.29 MiB/s 363.88 MiB/s]
134+
135+
wchar_wcstombs/astral_4byte
136+
[918.85 ns 997.60 ns 1.0930 us]
137+
[936.85 Melem/s 1.0265 Gelem/s 1.1144 Gelem/s]
138+
```
139+
140+
Encode improvement:
141+
142+
- Middle estimate: `17.148 us -> 997.60 ns`, `17.19x` faster.
143+
- Per-codepoint middle estimate: `16.746 ns/wc -> 0.974 ns/wc`.
144+
- Throughput middle estimate: `59.715 Melem/s -> 1.0265 Gelem/s`.
145+
146+
## Remaining
147+
148+
`bd-w7mtzu` should remain open for the 4-byte `mbstowcs` decode lane, which is
149+
still scalar and measured at `12.128 us` baseline / `10.994 us` post-control on
150+
this run. Re-profile it separately before changing decode.

0 commit comments

Comments
 (0)