Skip to content

Upgrade to fearless_simd v0.7 development state plus PR 300 - #1802

Closed
Shnatsel wants to merge 3 commits into
linebender:mainfrom
Shnatsel:fearless_simd_0.7_dev_update
Closed

Shnatsel wants to merge 3 commits into
linebender:mainfrom
Shnatsel:fearless_simd_0.7_dev_update

Conversation

@Shnatsel

@Shnatsel Shnatsel commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Shows the impact of linebender/fearless_simd#300 and other recent changes to fearless_simd

This is performance-neutral on x86 AVX2 on the Ghostscript tiger benchmarks.

AVX-512 is not comparable since main doesn't have AVX-512 support.

The new widen/narrow API is more boilerplate, but can work with hardware-width vectors such as S::f32s and can widen 512-bit vectors into two 512-bit vectors, which is inexpressible in the API that immediately combines the halves.

@LaurenzV

LaurenzV commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

NEON benchmarks are looking good as well.

@T-256

T-256 commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

unrelated to this PR, but I couldn't find any discussion to make simd optional feature (no simd types in final binary), is there any?
should it configurable from vello_common side or fearless_simd side?

I'm aware of fearless_simd support for disable multiversioning but it doesn't help much for binary-size concerns:

As a last resort, you can turn off multiversioning for specific SIMD instruction sets by passing --cfg disable_dispatch_sse4_2, --cfg disable_dispatch_avx2, or --cfg disable_dispatch_avx512 in RUSTFLAGS. These configuration flags only control automatic multiversioning. Disabling one does not remove its token type, its Simd implementation, or explicit kernel support; for example, an Avx2 token can still be used to call an AVX2 kernel when the CPU supports it.

@LaurenzV

LaurenzV commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Have you tried it? I'm pretty sure this should help with binary size, this was one of the main reasons to introduce this. It doesn't remove the tokens, but it should remove all instantiated functions used via the dispatch macro, which is what we use in vello.

Quik2007 pushed a commit to Quik2007/vello that referenced this pull request Sep 1, 2026
This PR bumps fearless_simd to version 0.7, which unfortunately contains
quite a few changes. Supersedes linebender#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.

``` 
ad268c3 vs 6d91522

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.
@LaurenzV

LaurenzV commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Superseded by #1853.

@LaurenzV LaurenzV closed this Sep 1, 2026
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