Skip to content

sparse_strips: Bump fearless_simd - #1853

Merged
LaurenzV merged 3 commits into
mainfrom
laurenz/bump_fm
Sep 1, 2026
Merged

LaurenzV merged 3 commits into
mainfrom
laurenz/bump_fm

Conversation

@LaurenzV

Copy link
Copy Markdown
Collaborator

This PR bumps fearless_simd to version 0.7, which unfortunately contains quite a few changes. Supersedes #1802.

Neon

Benchmarks are mostly neutral. There are two slight regressions: one for translucent unpremultiplication (where it seems like the new code results in different lowering from LLVM) and fill/transparent_short_u8_neon, where slightly different inlining decisions seem to be made. Unfortunately, there doesn't seem to be an easy fix for either, but they are so small that I don't think it's a problem. The other ones are mostly noise.

pixmap/premultiply/opaque
                        time:   [315.91 µs 316.09 µs 316.32 µs]
                        change: [+0.6858% +0.7933% +0.9047%] (p = 0.00 < 0.05)

pixmap/premultiply/translucent
                        time:   [313.42 µs 313.54 µs 313.67 µs]
                        change: [+0.1100% +0.1718% +0.2371%] (p = 0.00 < 0.05)

pixmap/unpremultiply/opaque
                        time:   [16.945 ns 17.425 ns 17.881 ns]
                        change: [-3.0579% +1.8470% +6.9649%] (p = 0.48 > 0.05)

pixmap/unpremultiply/translucent
                        time:   [840.16 µs 840.82 µs 841.99 µs]
                        change: [+5.6431% +6.5338% +8.0157%] (p = 0.00 < 0.05)

tile_aaa/Ghostscript_Tiger
                        time:   [105.11 µs 106.03 µs 107.28 µs]
                        change: [-3.3105% -2.0436% -0.7662%] (p = 0.00 < 0.05)

render_strips/Ghostscript_Tiger_simd
                        time:   [151.18 µs 151.25 µs 151.33 µs]
                        change: [-1.5969% -0.7500% -0.2867%] (p = 0.03 < 0.05)

render_rect/14x14_via_path
                        time:   [252.25 ns 252.44 ns 252.64 ns]
                        change: [-0.3993% -0.2674% -0.1142%] (p = 0.00 < 0.05)

render_rect/14x14_via_rect
                        time:   [49.306 ns 49.410 ns 49.601 ns]
                        change: [-0.0188% +0.2297% +0.6108%] (p = 0.19 > 0.05)

flatten/Ghostscript_Tiger
                        time:   [188.84 µs 189.44 µs 190.09 µs]
                        change: [-1.2633% -0.8082% -0.3760%] (p = 0.00 < 0.05)

strokes/Ghostscript_Tiger
                        time:   [130.60 µs 130.73 µs 130.89 µs]
                        change: [+0.3736% +0.5767% +0.8279%] (p = 0.00 < 0.05)

fine/fill/opaque_short_u8_neon
                        time:   [8.8827 ns 8.8857 ns 8.8895 ns]
                        change: [+0.1465% +0.2124% +0.2845%] (p = 0.00 < 0.05)

fine/fill/opaque_long_u8_neon
                        time:   [45.119 ns 45.248 ns 45.401 ns]
                        change: [-2.4963% -1.1467% +0.1225%] (p = 0.09 > 0.05)

fine/fill/transparent_short_u8_neon
                        time:   [18.750 ns 18.772 ns 18.793 ns]
                        change: [+9.4590% +9.7789% +10.177%] (p = 0.00 < 0.05)

fine/fill/transparent_long_u8_neon
                        time:   [110.05 ns 110.13 ns 110.21 ns]
                        change: [+2.5522% +2.6768% +2.8073%] (p = 0.00 < 0.05)

fine/strip/solid_single_u8_neon
                        time:   [10.714 ns 10.886 ns 11.059 ns]
                        change: [+0.3311% +2.7748% +5.3046%] (p = 0.03 < 0.05)

fine/strip/solid_short_u8_neon
                        time:   [14.698 ns 14.771 ns 14.864 ns]
                        change: [-1.6097% +0.0958% +2.1666%] (p = 0.92 > 0.05)

fine/strip/solid_medium_u8_neon
                        time:   [24.359 ns 24.375 ns 24.392 ns]
                        change: [+0.2068% +0.3743% +0.5460%] (p = 0.00 < 0.05)

fine/strip/solid_long_u8_neon
                        time:   [82.389 ns 82.449 ns 82.515 ns]
                        change: [-0.9429% -0.3986% +0.0602%] (p = 0.14 > 0.05)

fine/pack/pack_block_u8_neon
                        time:   [67.238 ns 67.370 ns 67.477 ns]
                        change: [-0.2522% -0.0805% +0.0987%] (p = 0.36 > 0.05)

fine/pack/unpack_block_u8_neon
                        time:   [68.959 ns 69.114 ns 69.356 ns]
                        change: [-0.3816% +0.2091% +0.8580%] (p = 0.54 > 0.05)

fine/gradient/linear/opaque_u8_neon
                        time:   [509.51 ns 521.12 ns 548.97 ns]
                        change: [-0.2671% +1.8120% +5.9169%] (p = 0.57 > 0.05)

fine/gradient/radial/opaque_u8_neon
                        time:   [648.67 ns 649.43 ns 650.14 ns]
                        change: [-0.2031% -0.0527% +0.0975%] (p = 0.51 > 0.05)

fine/gradient/sweep/opaque_u8_neon
                        time:   [1.2081 µs 1.2106 µs 1.2127 µs]
                        change: [-0.3143% -0.1488% +0.0148%] (p = 0.10 > 0.05)

fine/image/transform/scale_u8_neon
                        time:   [957.20 ns 958.29 ns 959.71 ns]
                        change: [-2.7575% -1.0166% +0.2629%] (p = 0.24 > 0.05)

fine/image/quality/low_u8_neon
                        time:   [957.73 ns 958.66 ns 959.33 ns]
                        change: [-0.2463% -0.1096% +0.0388%] (p = 0.16 > 0.05)

fine/image/quality/medium_u8_neon
                        time:   [2.4956 µs 2.4975 µs 2.4993 µs]
                        change: [-1.4322% +2.2680% +4.4770%] (p = 0.19 > 0.05)

AVX 2

Some improvements + regressions, but overall also within the noise threshold.

ad268c36 vs 6d915226

pixmap/premultiply/opaque
                        time:   [1.2310 ms 1.2328 ms 1.2348 ms]
                        change: [-3.8695% -3.7142% -3.5354%] (p = 0.00 < 0.05)

pixmap/premultiply/translucent
                        time:   [1.2331 ms 1.2354 ms 1.2385 ms]
                        change: [-4.1600% -3.8784% -3.5880%] (p = 0.00 < 0.05)

pixmap/unpremultiply/opaque
                        time:   [101.65 ns 102.54 ns 103.50 ns]
                        change: [-6.3807% -5.1246% -3.8709%] (p = 0.00 < 0.05)

pixmap/unpremultiply/translucent
                        time:   [1.4918 ms 1.4938 ms 1.4962 ms]
                        change: [-8.8167% -6.1277% -4.2415%] (p = 0.00 < 0.05)

tile_aaa/Ghostscript_Tiger
                        time:   [185.84 µs 186.25 µs 186.72 µs]
                        change: [+1.2903% +1.6085% +1.9419%] (p = 0.00 < 0.05)

tile_aaa/coat_of_arms
                        time:   [2.7779 ms 2.7858 ms 2.7963 ms]
                        change: [-4.5291% -3.4497% -2.2744%] (p = 0.00 < 0.05)

tile_aaa/gs_tiger
                        time:   [638.02 µs 638.67 µs 639.35 µs]
                        change: [-0.2708% +0.0227% +0.3856%] (p = 0.90 > 0.05)

render_strips/Ghostscript_Tiger_simd
                        time:   [290.51 µs 290.80 µs 291.13 µs]
                        change: [-1.3916% -1.2143% -1.0471%] (p = 0.00 < 0.05)

render_strips/coat_of_arms_simd
                        time:   [3.2823 ms 3.2877 ms 3.2932 ms]
                        change: [+0.6500% +0.7784% +0.9078%] (p = 0.00 < 0.05)

render_strips/gs_tiger_simd
                        time:   [1.0969 ms 1.0982 ms 1.0998 ms]
                        change: [-0.8750% -0.7246% -0.5627%] (p = 0.00 < 0.05)

render_rect/14x14_via_path
                        time:   [416.48 ns 416.90 ns 417.36 ns]
                        change: [-4.7792% -4.1552% -3.7032%] (p = 0.00 < 0.05)

render_rect/14x14_via_rect
                        time:   [194.52 ns 194.70 ns 194.93 ns]
                        change: [-1.0519% -0.9056% -0.7333%] (p = 0.00 < 0.05)

flatten/Ghostscript_Tiger
                        time:   [305.44 µs 305.87 µs 306.35 µs]
                        change: [-0.3814% -0.1895% +0.0013%] (p = 0.05 > 0.05)

flatten/coat_of_arms
                        time:   [1.5737 ms 1.5768 ms 1.5809 ms]
                        change: [+0.0934% +0.3903% +0.8028%] (p = 0.01 < 0.05)

flatten/gs_tiger
                        time:   [374.07 µs 374.70 µs 375.40 µs]
                        change: [-0.7730% -0.1384% +0.4496%] (p = 0.67 > 0.05)

strokes/Ghostscript_Tiger
                        time:   [231.63 µs 231.84 µs 232.07 µs]
                        change: [-2.4373% -2.2960% -2.1382%] (p = 0.00 < 0.05)

strokes/coat_of_arms
                        time:   [2.4986 ms 2.5022 ms 2.5062 ms]
                        change: [-3.1653% -2.9797% -2.7822%] (p = 0.00 < 0.05)

strokes/gs_tiger
                        time:   [369.37 µs 369.67 µs 369.99 µs]
                        change: [-1.9221% -1.8193% -1.7068%] (p = 0.00 < 0.05)

fine/fill/opaque_short_u8_sse4_2
                        time:   [13.970 ns 14.025 ns 14.076 ns]
                        change: [+12.251% +13.338% +14.422%] (p = 0.00 < 0.05)

fine/fill/opaque_short_u8_avx2
                        time:   [10.865 ns 11.455 ns 12.048 ns]
                        change: [-7.9990% -3.1434% +2.3331%] (p = 0.24 > 0.05)

fine/fill/opaque_long_u8_sse4_2
                        time:   [55.306 ns 55.382 ns 55.477 ns]
                        change: [-0.2167% +0.0470% +0.3573%] (p = 0.75 > 0.05)

fine/fill/opaque_long_u8_avx2
                        time:   [41.182 ns 46.591 ns 52.543 ns]
                        change: [-19.370% -8.9733% +2.4962%] (p = 0.14 > 0.05)

fine/fill/transparent_short_u8_sse4_2
                        time:   [38.317 ns 38.397 ns 38.494 ns]
                        change: [+0.4434% +0.7840% +1.1931%] (p = 0.00 < 0.05)

fine/fill/transparent_short_u8_avx2
                        time:   [24.496 ns 24.646 ns 24.811 ns]
                        change: [+0.7373% +1.2710% +2.0074%] (p = 0.00 < 0.05)

fine/fill/transparent_long_u8_sse4_2
                        time:   [289.77 ns 290.23 ns 290.70 ns]
                        change: [-0.1751% +0.4127% +0.7947%] (p = 0.09 > 0.05)

fine/fill/transparent_long_u8_avx2
                        time:   [175.43 ns 175.88 ns 176.36 ns]
                        change: [-6.2799% -5.3178% -4.3607%] (p = 0.00 < 0.05)

fine/strip/solid_single_u8_sse4_2
                        time:   [17.075 ns 17.089 ns 17.105 ns]
                        change: [-19.262% -19.151% -19.052%] (p = 0.00 < 0.05)

fine/strip/solid_single_u8_avx2
                        time:   [12.965 ns 13.022 ns 13.121 ns]
                        change: [+0.9289% +1.2096% +1.5814%] (p = 0.00 < 0.05)

fine/strip/solid_short_u8_sse4_2
                        time:   [30.467 ns 30.487 ns 30.510 ns]
                        change: [-10.316% -10.120% -9.9435%] (p = 0.00 < 0.05)

fine/strip/solid_short_u8_avx2
                        time:   [21.728 ns 21.743 ns 21.760 ns]
                        change: [+0.7115% +0.8207% +0.9339%] (p = 0.00 < 0.05)

fine/strip/solid_medium_u8_sse4_2
                        time:   [58.098 ns 58.160 ns 58.229 ns]
                        change: [-6.1832% -5.9589% -5.7600%] (p = 0.00 < 0.05)

fine/strip/solid_medium_u8_avx2
                        time:   [39.536 ns 39.582 ns 39.638 ns]
                        change: [+0.6650% +1.1000% +1.4204%] (p = 0.00 < 0.05)

fine/strip/solid_long_u8_sse4_2
                        time:   [223.90 ns 224.04 ns 224.20 ns]
                        change: [-1.3438% -1.1719% -0.9902%] (p = 0.00 < 0.05)

fine/strip/solid_long_u8_avx2
                        time:   [146.24 ns 146.88 ns 148.06 ns]
                        change: [-2.7791% -2.5403% -2.2207%] (p = 0.00 < 0.05)

fine/pack/pack_block_u8_sse4_2
                        time:   [168.91 ns 169.10 ns 169.32 ns]
                        change: [+0.7316% +0.8698% +1.0147%] (p = 0.00 < 0.05)

fine/pack/pack_block_u8_avx2
                        time:   [168.94 ns 169.17 ns 169.45 ns]
                        change: [+0.6180% +0.7064% +0.8046%] (p = 0.00 < 0.05)

fine/pack/unpack_block_u8_sse4_2
                        time:   [168.86 ns 169.00 ns 169.15 ns]
                        change: [-0.2083% +0.1919% +0.5369%] (p = 0.33 > 0.05)

fine/pack/unpack_block_u8_avx2
                        time:   [170.10 ns 170.32 ns 170.53 ns]
                        change: [+0.4522% +0.6053% +0.7450%] (p = 0.00 < 0.05)

fine/gradient/linear/opaque_u8_sse4_2
                        time:   [791.22 ns 792.37 ns 793.68 ns]
                        change: [+0.4094% +0.5898% +0.7695%] (p = 0.00 < 0.05)

fine/gradient/linear/opaque_u8_avx2
                        time:   [752.02 ns 755.78 ns 760.06 ns]
                        change: [+0.6480% +1.6757% +2.5851%] (p = 0.00 < 0.05)

fine/gradient/radial/opaque_u8_sse4_2
                        time:   [1.1267 µs 1.1279 µs 1.1293 µs]
                        change: [-0.1485% -0.0375% +0.0761%] (p = 0.51 > 0.05)

fine/gradient/radial/opaque_u8_avx2
                        time:   [979.83 ns 984.20 ns 988.81 ns]
                        change: [+1.2970% +1.8363% +2.3780%] (p = 0.00 < 0.05)

fine/gradient/sweep/opaque_u8_sse4_2
                        time:   [2.1444 µs 2.1455 µs 2.1467 µs]
                        change: [+0.0197% +0.1736% +0.3016%] (p = 0.01 < 0.05)

fine/gradient/sweep/opaque_u8_avx2
                        time:   [1.6136 µs 1.6225 µs 1.6331 µs]
                        change: [+1.0502% +1.4864% +1.9558%] (p = 0.00 < 0.05)

fine/image/transform/scale_u8_sse4_2
                        time:   [835.01 ns 835.63 ns 836.30 ns]
                        change: [-5.0927% -4.9640% -4.8460%] (p = 0.00 < 0.05)

fine/image/transform/scale_u8_avx2
                        time:   [819.53 ns 821.37 ns 823.15 ns]
                        change: [-1.4932% -1.3225% -1.1370%] (p = 0.00 < 0.05)

fine/image/quality/low_u8_sse4_2
                        time:   [834.28 ns 834.79 ns 835.32 ns]
                        change: [-5.4273% -5.2732% -5.1430%] (p = 0.00 < 0.05)

fine/image/quality/low_u8_avx2
                        time:   [821.71 ns 822.67 ns 823.60 ns]
                        change: [-1.3512% -1.1938% -1.0545%] (p = 0.00 < 0.05)

fine/image/quality/medium_u8_sse4_2
                        time:   [5.3126 µs 5.3151 µs 5.3180 µs]
                        change: [-1.1460% -1.0265% -0.9061%] (p = 0.00 < 0.05)

fine/image/quality/medium_u8_avx2
                        time:   [4.5307 µs 4.5325 µs 4.5346 µs]
                        change: [-1.9957% -1.8938% -1.7974%] (p = 0.00 < 0.05)

WASM

I didn't run extensive benchmarks but I've tried rendering GhostScript tiger on my potato tablet, and the frame rate seems unchanged across the two commits.

Comment on lines 639 to +790
@@ -789,11 +786,8 @@ impl Tiles {
let target_row = &mut self.windings.partial[y_idx as usize];
let current = f32x4::from_slice(s, target_row);

let double_count = if crosses_top {
f_dir_v
} else {
f32x4::splat(s, 0.0)
};
let double_count = mask32x4::splat(s, crosses_top)
.select(f_dir_v, f32x4::splat(s, 0.0));

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On AVX2 wit the old code I got a regression of around 25% with new fearless_simd, because the branchless selects were turned into branches. These two changes fix this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also use std's select_unpredictable here to keep the logic in the scalar domain. I don't know if that will give you any performance benefits or not.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I think I'll keep it for now since I've already benchmarked this, but thanks for pointing it out!

Comment thread .github/workflows/ci.yml
- name: cargo test --doc
run: cargo test --doc --workspace --locked --all-features --no-fail-fast

test-avx512:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m concerned this adds more CI time by rerunning nearly the entire test suite for relatively uncommon AVX-512 hardware. Could we keep SSE2 coverage but run AVX-512 only when SIMD-related code changes, or in a nightly/weekly scheduled workflow instead of on every PR?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not nearly as bad as it appears. CI time for this job is under 3 minutes; it does not make CI take longer overall.

And it's not as uncommon as you might expect. Steam hardware survey puts AVX-512 availability at 23%, which is far ahead of both SSE4.2-only (2%) and SSE2-only (1%) systems in their data.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would agree with @Shnatsel here, it definitely doesn't impact CI run times since it's not even close to being the bottleneck, and AVX-512 is not that uncommon anymore, especially on server hardware, which is also relevant for our internal use cases. The only downside is that it makes the CI file uglier. So unless you are strongly opposed, I think it would be better to keep this.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beyond runner time, this brings the workflow to 21 jobs while Linebender’s Free plan allows 20 concurrent GitHub-hosted jobs. The AVX-512 job took ~4 minutes and finished well before the slowest job, so it likely won’t materially increase total CI duration, but it can still occupy a scarce slot and cause queueing when the organization is busy.

Anyway, I’m not blocking this — just expressing concern about the gradual increase in CI infra usage, which I think we’ll need to address in the near future.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SSE4.2-only (2%) and SSE2-only (1%)

Just to clarify, what do you mean by “SSE4.2-only (2%) and SSE2-only (1%)” here? The Steam survey seems to report support for each instruction set independently rather than mutually exclusive “only” buckets.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I subtracted the AVX2 percentage from the SSE4.2 to get "SSE4.2 only". Same for "SSE2 only": SSE2 - SSE4.2.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, didn't know about the 20 concurrent jobs limit, thanks for pointing it out!

Comment thread Cargo.toml
crossbeam-channel = "0.5.15"
ordered-channel = { version = "1.2.0", features = ["crossbeam-channel"] }
fearless_simd = { version = "0.4.0", default-features = false }
fearless_simd = { version = "0.7.0", default-features = false }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add browser wasm support to the benchmark harness? The web is an important target for us, and this would give us much better insight into its performance; once supported, it would also be useful to rerun the benchmarks for this fearless_simd bump to identify any improvements/regressions.

Base automatically changed from laurenz/benches to main August 31, 2026 05:54
@LaurenzV

Copy link
Copy Markdown
Collaborator Author

Added a make-shift WASM harness: laurenz-canva/vello_bench2@master...wasm_bench

Here are the results on my Mac:

Benchmark Scalar before Scalar after Scalar Δ SIMD128 before SIMD128 after SIMD128 Δ
pixmap/premultiply/opaque 3.30 ms 3.29 ms -0.2% 456.05 µs 456.95 µs +0.2%
pixmap/premultiply/translucent 3.33 ms 3.34 ms +0.3% 457.93 µs 456.52 µs -0.3%
pixmap/unpremultiply/opaque 201.1 ns 191.0 ns -5.1% 200.7 ns 169.4 ns -15.6%
pixmap/unpremultiply/translucent 3.19 ms 3.21 ms +0.8% 713.48 µs 717.79 µs +0.6%
tile_aaa/Ghostscript_Tiger 64.41 µs 63.92 µs -0.8% 63.94 µs 63.40 µs -0.8%
render_strips/Ghostscript_Tiger 819.72 µs 806.17 µs -1.7% 158.98 µs 160.57 µs +1.0%
render_rect/14x14_via_path 880.9 ns 881.3 ns +0.0% 371.1 ns 369.0 ns -0.5%
render_rect/14x14_via_rect 277.2 ns 281.9 ns +1.7% 271.4 ns 265.7 ns -2.1%
flatten/Ghostscript_Tiger 284.70 µs 284.84 µs +0.0% 154.04 µs 153.17 µs -0.6%
strokes/Ghostscript_Tiger 161.85 µs 157.60 µs -2.6% 140.72 µs 138.90 µs -1.3%
fine/fill/opaque_short_u8 233.3 ns 238.2 ns +2.1% 232.5 ns 230.7 ns -0.8%
fine/fill/opaque_long_u8 350.9 ns 346.9 ns -1.1% 285.0 ns 284.3 ns -0.2%
fine/fill/transparent_short_u8 435.3 ns 435.4 ns +0.0% 235.4 ns 229.5 ns -2.5%
fine/fill/transparent_long_u8 1.93 µs 1.91 µs -1.4% 353.1 ns 352.1 ns -0.3%
fine/strip/solid_single_u8 286.8 ns 281.2 ns -1.9% 225.8 ns 221.7 ns -1.8%
fine/strip/solid_short_u8 354.4 ns 352.4 ns -0.6% 229.7 ns 227.6 ns -0.9%
fine/strip/solid_medium_u8 490.8 ns 489.2 ns -0.3% 239.2 ns 230.5 ns -3.6%
fine/strip/solid_long_u8 1.30 µs 1.27 µs -2.0% 301.3 ns 299.7 ns -0.5%
fine/pack/pack_block_u8 421.1 ns 423.1 ns +0.5% 358.4 ns 346.3 ns -3.4%
fine/pack/unpack_block_u8 425.8 ns 446.1 ns +4.8% 349.2 ns 333.1 ns -4.6%
fine/gradient/linear/opaque_u8 1.33 µs 1.33 µs +0.1% 713.2 ns 704.7 ns -1.2%
fine/gradient/radial/opaque_u8 1.95 µs 1.98 µs +1.2% 865.8 ns 856.5 ns -1.1%
fine/gradient/sweep/opaque_u8 3.69 µs 3.73 µs +0.9% 1.34 µs 1.35 µs +0.4%
fine/image/transform/scale_u8 1.74 µs 1.74 µs -0.0% 654.4 ns 657.8 ns +0.5%
fine/image/quality/low_u8 1.76 µs 1.75 µs -0.5% 653.5 ns 666.9 ns +2.0%
fine/image/quality/medium_u8 9.78 µs 9.64 µs -1.4% 2.06 µs 2.08 µs +0.6%

I also tried running on an older MacBook on BrowserStack as well as a phone, but the results are just way too noisy to draw any real conclusions, but the results were usually withint +/- 10%.

But I haven't noticed any real big regressions that were consistently reproducible.

@LaurenzV
LaurenzV requested a review from grebmeg August 31, 2026 06:51

@grebmeg grebmeg left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also tried running on an older MacBook on BrowserStack as well as a phone, but the results are just way too noisy to draw any real conclusions, but the results were usually withint +/- 10%.

But I haven't noticed any real big regressions that were consistently reproducible.

Nice! LGTM! Thanks for doing this! As a follow-up, could we productionize your branch and add it here?

Comment thread .github/workflows/ci.yml
- name: cargo test --doc
run: cargo test --doc --workspace --locked --all-features --no-fail-fast

test-avx512:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beyond runner time, this brings the workflow to 21 jobs while Linebender’s Free plan allows 20 concurrent GitHub-hosted jobs. The AVX-512 job took ~4 minutes and finished well before the slowest job, so it likely won’t materially increase total CI duration, but it can still occupy a scarce slot and cause queueing when the organization is busy.

Anyway, I’m not blocking this — just expressing concern about the gradual increase in CI infra usage, which I think we’ll need to address in the near future.

@LaurenzV

LaurenzV commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator Author

Will see what I can do. But as mentioned, unforutnately it's not straightforward because because our criterion-based setup doesn't really work in WASM. But I also don't want to duplicate all benchmark methods just for WASM!

@LaurenzV
LaurenzV added this pull request to the merge queue Sep 1, 2026
Merged via the queue into main with commit 71aa603 Sep 1, 2026
21 checks passed
@LaurenzV
LaurenzV deleted the laurenz/bump_fm branch September 1, 2026 05:52
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.

3 participants