Skip to content

Faster UTF-32 to UTF-16 on Westmere - #708

Merged
WojciechMula merged 1 commit into
simdutf:masterfrom
WojciechMula:westmere-utf32-to-utf16
Mar 23, 2025
Merged

Faster UTF-32 to UTF-16 on Westmere#708
WojciechMula merged 1 commit into
simdutf:masterfrom
WojciechMula:westmere-utf32-to-utf16

Conversation

@WojciechMula

@WojciechMula WojciechMula commented Mar 6, 2025

Copy link
Copy Markdown
Collaborator

Use vectorized code to handle surrogate pairs generation. For now in Westmere kernel.

Result for:

# verify no regresion 
./benchmark -P convert_utf32_to_utf16le+westmere -F ~/github/unicode_lipsum/wikipedia_mars/*.utf32.txt -I 1000 > $1.conv.txt

# check surrogate conversion
./benchmark -P convert_utf32_to_utf16le+westmere -F ~/github/unicode_lipsum/utf32_to_utf16/*.utf32.txt -I 1000 > $1.surr.txt

There are no performance regressions for the common case (no surrogates path), the vectorized building surrogate pairs is really fast. It cost us 2*16*16 bytes = 0.5kB additional lookup tables.

Ryzen

dataset size [B] iterations old GB/s new GB/s speedup
convert_utf32_to_utf16le+westmere
arabic.utf32 1699376 1000 47.96 47.74 1.00x
chinese.utf32 548832 1000 45.23 47.97 1.06x
czech.utf32 575328 1000 48.14 47.82 0.99x
english.utf32 1550036 1000 48.00 47.68 0.99x
esperanto.utf32 336500 1000 47.51 47.44 1.00x
french.utf32 1739468 1000 47.91 47.70 1.00x
german.utf32 804860 1000 48.05 47.85 1.00x
greek.utf32 571996 1000 47.50 47.78 1.01x
hebrew.utf32 585404 1000 47.97 47.39 0.99x
hindi.utf32 1095832 1000 48.10 47.85 0.99x
japanese.utf32 475564 1000 48.00 46.95 0.98x
korean.utf32 291672 1000 48.04 47.41 0.99x
persan.utf32 498776 1000 47.55 47.60 1.00x
portuguese.utf32 1094456 1000 47.35 47.37 1.00x
russian.utf32 1248148 1000 47.39 47.03 0.99x
thai.utf32 1619032 1000 47.68 47.92 1.01x
turkish.utf32 741768 1000 48.05 47.74 0.99x
vietnamese.utf32 1129676 1000 47.94 47.76 1.00x
dataset size [B] iterations old GB/s new GB/s speedup
convert_utf32_to_utf16le+westmere
256k_000perc_surrogates.utf32 1048576 1000 46.48 47.81 1.03x
256k_005perc_surrogates.utf32 1048576 1000 6.16 16.48 2.67x
256k_025perc_surrogates.utf32 1048576 1000 2.40 11.04 4.60x
256k_033perc_surrogates.utf32 1048576 1000 1.93 11.12 5.75x
256k_050perc_surrogates.utf32 1048576 1000 1.50 11.19 7.48x
256k_075perc_surrogates.utf32 1048576 1000 2.30 11.26 4.89x
256k_095perc_surrogates.utf32 1048576 1000 5.16 11.21 2.17x
64k_000perc_surrogates.utf32 262144 1000 47.32 47.23 1.00x
64k_005perc_surrogates.utf32 262144 1000 18.46 16.67 0.90x
64k_025perc_surrogates.utf32 262144 1000 3.69 11.19 3.03x
64k_033perc_surrogates.utf32 262144 1000 2.56 11.24 4.39x
64k_050perc_surrogates.utf32 262144 1000 1.86 11.20 6.02x
64k_075perc_surrogates.utf32 262144 1000 6.87 11.16 1.62x
64k_095perc_surrogates.utf32 262144 1000 6.47 11.28 1.74x

Skylake-X

dataset size [B] iterations old GB/s new GB/s speedup
convert_utf32_to_utf16le+westmere
arabic.utf32 1699376 1000 12.34 13.08 1.06x
chinese.utf32 548832 1000 14.34 23.78 1.66x
czech.utf32 575328 1000 14.21 21.85 1.54x
english.utf32 1550036 1000 12.33 13.09 1.06x
esperanto.utf32 336500 1000 14.23 25.02 1.76x
french.utf32 1739468 1000 12.35 13.09 1.06x
german.utf32 804860 1000 13.61 16.50 1.21x
greek.utf32 571996 1000 14.34 23.66 1.65x
hebrew.utf32 585404 1000 14.17 21.92 1.55x
hindi.utf32 1095832 1000 12.69 13.61 1.07x
japanese.utf32 475564 1000 14.31 24.35 1.70x
korean.utf32 291672 1000 14.18 24.91 1.76x
persan.utf32 498776 1000 14.32 23.68 1.65x
portuguese.utf32 1094456 1000 12.73 13.68 1.07x
russian.utf32 1248148 1000 13.27 13.60 1.02x
thai.utf32 1619032 1000 12.54 13.19 1.05x
turkish.utf32 741768 1000 14.00 18.16 1.30x
vietnamese.utf32 1129676 1000 12.82 13.88 1.08x
dataset size [B] iterations old GB/s new GB/s speedup
convert_utf32_to_utf16le+westmere
256k_000perc_surrogates.utf32 1048576 1000 12.97 13.96 1.08x
256k_005perc_surrogates.utf32 1048576 1000 2.55 5.74 2.25x
256k_025perc_surrogates.utf32 1048576 1000 1.01 5.53 5.47x
256k_033perc_surrogates.utf32 1048576 1000 0.82 5.51 6.69x
256k_050perc_surrogates.utf32 1048576 1000 0.65 5.52 8.45x
256k_075perc_surrogates.utf32 1048576 1000 0.71 5.52 7.76x
256k_095perc_surrogates.utf32 1048576 1000 0.88 5.52 6.26x
64k_000perc_surrogates.utf32 262144 1000 14.15 24.80 1.75x
64k_005perc_surrogates.utf32 262144 1000 3.31 7.56 2.28x
64k_025perc_surrogates.utf32 262144 1000 1.04 5.51 5.31x
64k_033perc_surrogates.utf32 262144 1000 0.84 5.49 6.52x
64k_050perc_surrogates.utf32 262144 1000 0.66 5.50 8.33x
64k_075perc_surrogates.utf32 262144 1000 0.72 5.51 7.66x
64k_095perc_surrogates.utf32 262144 1000 0.91 5.47 6.03x

IceLake

dataset size [B] iterations old GB/s new GB/s speedup
convert_utf32_to_utf16le+westmere
arabic.utf32 1699376 1000 14.19 18.80 1.33x
chinese.utf32 548832 1000 15.92 29.55 1.86x
czech.utf32 575328 1000 15.92 29.53 1.85x
english.utf32 1550036 1000 14.63 19.48 1.33x
esperanto.utf32 336500 1000 15.88 29.46 1.85x
french.utf32 1739468 1000 19.42 18.88 0.97x
german.utf32 804860 1000 24.94 30.50 1.22x
greek.utf32 571996 1000 25.45 29.41 1.16x
hebrew.utf32 585404 1000 25.28 29.56 1.17x
hindi.utf32 1095832 1000 21.82 21.65 0.99x
japanese.utf32 475564 1000 25.45 29.63 1.16x
korean.utf32 291672 1000 25.39 29.57 1.16x
persan.utf32 498776 1000 25.44 32.42 1.27x
portuguese.utf32 1094456 1000 21.09 21.43 1.02x
russian.utf32 1248148 1000 20.17 19.73 0.98x
thai.utf32 1619032 1000 20.25 19.43 0.96x
turkish.utf32 741768 1000 25.16 29.14 1.16x
vietnamese.utf32 1129676 1000 20.91 20.81 1.00x
dataset size [B] iterations old GB/s new GB/s speedup
convert_utf32_to_utf16le+westmere
256k_000perc_surrogates.utf32 1048576 1000 14.27 16.27 1.14x
256k_005perc_surrogates.utf32 1048576 1000 4.01 6.05 1.51x
256k_025perc_surrogates.utf32 1048576 1000 1.50 6.27 4.19x
256k_033perc_surrogates.utf32 1048576 1000 1.19 6.25 5.24x
256k_050perc_surrogates.utf32 1048576 1000 0.95 6.25 6.60x
256k_075perc_surrogates.utf32 1048576 1000 1.41 6.26 4.45x
256k_095perc_surrogates.utf32 1048576 1000 3.10 6.28 2.02x
64k_000perc_surrogates.utf32 262144 1000 25.40 29.56 1.16x
64k_005perc_surrogates.utf32 262144 1000 8.30 9.38 1.13x
64k_025perc_surrogates.utf32 262144 1000 1.95 6.29 3.23x
64k_033perc_surrogates.utf32 262144 1000 1.43 6.29 4.39x
64k_050perc_surrogates.utf32 262144 1000 1.08 6.31 5.81x
64k_075perc_surrogates.utf32 262144 1000 1.74 6.30 3.63x
64k_095perc_surrogates.utf32 262144 1000 3.96 6.32 1.60x

@WojciechMula
WojciechMula force-pushed the westmere-utf32-to-utf16 branch 2 times, most recently from 9a8a785 to 870d4c5 Compare March 20, 2025 17:45
@WojciechMula

Copy link
Copy Markdown
Collaborator Author

As usual, I'd like to update other targets gradually.

@WojciechMula
WojciechMula marked this pull request as ready for review March 20, 2025 18:09
@WojciechMula WojciechMula changed the title [WiP] Even faster UTF-32 to UTF-16 Faster UTF-32 to UTF-16 on Westmere Mar 20, 2025
Use vectorized handling of surrogates. The lookup tables for
this are not that big.
@WojciechMula
WojciechMula force-pushed the westmere-utf32-to-utf16 branch from 870d4c5 to bee2c75 Compare March 21, 2025 20:42
@WojciechMula
WojciechMula merged commit 4fc236a into simdutf:master Mar 23, 2025
@WojciechMula
WojciechMula deleted the westmere-utf32-to-utf16 branch March 23, 2025 09:05
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.

2 participants