Skip to content

Light up core ASCII.Utility methods with Vector256/Vector512 code paths. - #88532

Merged
tannergooding merged 9 commits into
dotnet:mainfrom
anthonycanino:LibUpAscii
Jul 17, 2023
Merged

Light up core ASCII.Utility methods with Vector256/Vector512 code paths.#88532
tannergooding merged 9 commits into
dotnet:mainfrom
anthonycanino:LibUpAscii

Conversation

@anthonycanino

@anthonycaninoanthonycanino commented Jul 7, 2023

Copy link
Copy Markdown
Contributor

This PR lights up some code path in ASCII.Utility with Vector256/Vector512 code, namely, NarrowUtf16ToAscii, WidenAsciiToUtf16, GetIndexOfFirstNonAsciiChar, and GetIndexOfFirstNonAsciiByte.

For the GetIndexOfMethods, we have implemented the simpler, existing "default" code path but with the explicty VectorXX apis; for the Narrow/Widen methods, we have implemented the more complex SSE/Vector256 path but with the Vector256/Vector512 APIs. Right now, both are a slight tradeoff in terms of code complexity/performance.

We are open to adjusting the implementation style for either path. Perf numbers coming soon.

Perf

Please see the next section for the raw data collected from the utf8 case for System.Text.Tests.Perf_Encoding. I have formatted it a bit here to make it slightly easier to draw conclusions. Essentially, I have run with a base, run with Enable_AVX512F=1 for the vector512 path, and with Enable_AVX512F=0 for the vector256 path.

The micro is run with...

runtime\dotnet.cmd run -c Release -f net8.0 --filter System.Text.Tests.Perf_Encoding.* --corerun runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe

I have added some additional data sizes and an additional micro GetCharCount which simply invokes enc.GetCharCount analogous to GetByteCount. I call out some speedup with green, and some slowdown with orange.

GetBytes

image

GetChars

image

GetByteCount

image

GetCharCount

image

Raw Results from Two Runs

With DOTNET_AVX512F=1

MethodJobToolchainsizeencNameMeanErrorStdDevMedianMinMaxRatioRatioSDGen0Gen1AllocatedAlloc Ratio
GetBytesJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-816.870 ns0.3963 ns0.4069 ns16.946 ns16.094 ns17.412 ns1.000.000.0021-40 B1.00
GetBytesJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-817.409 ns0.3935 ns0.3865 ns17.524 ns16.928 ns18.138 ns1.030.030.0021-40 B1.00
GetCharsJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-824.459 ns0.5415 ns0.5561 ns24.677 ns23.679 ns25.508 ns1.000.000.0029-56 B1.00
GetCharsJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-826.097 ns0.4077 ns0.3814 ns26.229 ns25.364 ns26.878 ns1.070.030.0029-56 B1.00
GetByteCountJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-89.204 ns0.4215 ns0.4853 ns9.283 ns7.837 ns9.642 ns1.000.00---NA
GetByteCountJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-88.027 ns0.0503 ns0.0392 ns8.017 ns7.981 ns8.081 ns0.880.07---NA
GetCharCountJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-85.928 ns0.0466 ns0.0413 ns5.924 ns5.882 ns5.993 ns1.000.00---NA
GetCharCountJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-87.510 ns0.1455 ns0.1361 ns7.429 ns7.360 ns7.777 ns1.270.03---NA
GetBytesJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-816.694 ns0.1554 ns0.1213 ns16.644 ns16.571 ns16.952 ns1.000.000.0029-56 B1.00
GetBytesJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-816.070 ns0.0626 ns0.0523 ns16.075 ns15.967 ns16.149 ns0.960.010.0029-56 B1.00
GetCharsJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-825.220 ns0.1805 ns0.1600 ns25.204 ns25.009 ns25.451 ns1.000.000.0046-88 B1.00
GetCharsJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-825.691 ns0.2295 ns0.1916 ns25.649 ns25.316 ns25.995 ns1.020.010.0046-88 B1.00
GetByteCountJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-88.251 ns0.0137 ns0.0121 ns8.254 ns8.223 ns8.265 ns1.000.00---NA
GetByteCountJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-87.585 ns0.0211 ns0.0198 ns7.585 ns7.552 ns7.623 ns0.920.00---NA
GetCharCountJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-86.889 ns0.1059 ns0.0939 ns6.913 ns6.563 ns6.924 ns1.000.00---NA
GetCharCountJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-87.681 ns0.0036 ns0.0030 ns7.681 ns7.675 ns7.686 ns1.120.02---NA
GetBytesJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-830.093 ns0.1604 ns0.1339 ns30.134 ns29.827 ns30.335 ns1.000.000.0046-88 B1.00
GetBytesJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-829.859 ns0.2332 ns0.2068 ns29.885 ns29.535 ns30.140 ns0.990.010.0046-88 B1.00
GetCharsJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-829.528 ns0.2547 ns0.2258 ns29.507 ns29.246 ns30.069 ns1.000.000.0081-152 B1.00
GetCharsJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-831.390 ns0.2142 ns0.1899 ns31.411 ns30.957 ns31.668 ns1.060.010.0080-152 B1.00
GetByteCountJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-89.404 ns0.0206 ns0.0192 ns9.404 ns9.366 ns9.435 ns1.000.00---NA
GetByteCountJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-89.203 ns0.0503 ns0.0471 ns9.209 ns9.094 ns9.255 ns0.980.01---NA
GetCharCountJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-87.445 ns0.0030 ns0.0027 ns7.446 ns7.440 ns7.448 ns1.000.00---NA
GetCharCountJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-88.367 ns0.0072 ns0.0064 ns8.367 ns8.356 ns8.379 ns1.120.00---NA
GetBytesJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-836.796 ns0.2551 ns0.2261 ns36.797 ns36.321 ns37.218 ns1.000.000.0081-152 B1.00
GetBytesJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-836.670 ns0.2703 ns0.2396 ns36.661 ns36.354 ns37.150 ns1.000.010.0080-152 B1.00
GetCharsJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-837.293 ns0.3142 ns0.2785 ns37.330 ns36.756 ns37.780 ns1.000.000.0148-280 B1.00
GetCharsJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-838.340 ns0.2087 ns0.1850 ns38.320 ns38.038 ns38.642 ns1.030.010.0148-280 B1.00
GetByteCountJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-811.914 ns0.0415 ns0.0388 ns11.923 ns11.815 ns11.957 ns1.000.00---NA
GetByteCountJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-810.412 ns0.0483 ns0.0452 ns10.415 ns10.317 ns10.499 ns0.870.01---NA
GetCharCountJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-88.595 ns0.0078 ns0.0069 ns8.597 ns8.580 ns8.606 ns1.000.00---NA
GetCharCountJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-811.532 ns0.0134 ns0.0119 ns11.531 ns11.514 ns11.553 ns1.340.00---NA
GetBytesJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-850.754 ns0.0815 ns0.0637 ns50.762 ns50.649 ns50.848 ns1.000.000.0148-280 B1.00
GetBytesJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-846.471 ns0.0475 ns0.0397 ns46.468 ns46.417 ns46.560 ns0.920.000.0149-280 B1.00
GetCharsJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-853.838 ns0.4639 ns0.4112 ns53.651 ns53.322 ns54.746 ns1.000.000.0284-536 B1.00
GetCharsJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-854.503 ns1.1033 ns0.9780 ns54.805 ns53.152 ns56.528 ns1.010.020.0283-536 B1.00
GetByteCountJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-816.165 ns0.1093 ns0.1023 ns16.188 ns15.907 ns16.303 ns1.000.00---NA
GetByteCountJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-814.100 ns0.2427 ns0.2270 ns14.222 ns13.641 ns14.296 ns0.870.02---NA
GetCharCountJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-811.281 ns0.0065 ns0.0061 ns11.284 ns11.268 ns11.287 ns1.000.00---NA
GetCharCountJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-812.991 ns0.0526 ns0.0492 ns12.991 ns12.927 ns13.075 ns1.150.00---NA
GetBytesJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-884.888 ns0.6871 ns0.5738 ns85.025 ns83.542 ns85.490 ns1.000.000.0283-536 B1.00
GetBytesJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-871.747 ns0.9126 ns0.8536 ns71.638 ns70.464 ns73.243 ns0.840.010.0283-536 B1.00
GetCharsJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-890.956 ns1.3016 ns1.1538 ns90.855 ns89.107 ns93.114 ns1.000.000.0556-1048 B1.00
GetCharsJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-888.008 ns0.4077 ns0.3615 ns87.946 ns87.422 ns88.657 ns0.970.010.0555-1048 B1.00
GetByteCountJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-824.785 ns0.1321 ns0.1171 ns24.794 ns24.454 ns24.955 ns1.000.00---NA
GetByteCountJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-815.675 ns0.0271 ns0.0254 ns15.681 ns15.625 ns15.708 ns0.630.00---NA
GetCharCountJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-815.559 ns0.0052 ns0.0046 ns15.559 ns15.551 ns15.567 ns1.000.00---NA
GetCharCountJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-816.235 ns0.0329 ns0.0308 ns16.235 ns16.191 ns16.305 ns1.040.00---NA
GetBytesJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-8174.537 ns1.2549 ns1.1124 ns174.597 ns172.235 ns176.644 ns1.000.000.0550-1048 B1.00
GetBytesJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-8129.363 ns1.2396 ns1.0988 ns129.508 ns127.232 ns130.718 ns0.740.010.0556-1048 B1.00
GetCharsJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-8170.690 ns1.3975 ns1.2389 ns170.792 ns168.408 ns172.876 ns1.000.000.11000.00072072 B1.00
GetCharsJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-8148.640 ns0.3393 ns0.2833 ns148.566 ns148.082 ns149.138 ns0.870.010.11000.00072072 B1.00
GetByteCountJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-851.289 ns0.2287 ns0.2140 ns51.320 ns50.601 ns51.489 ns1.000.00---NA
GetByteCountJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-834.275 ns1.2877 ns1.4829 ns34.238 ns31.380 ns36.673 ns0.660.03---NA
GetCharCountJob-GLULPR\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-833.042 ns0.6956 ns0.7143 ns33.531 ns31.532 ns33.683 ns1.000.00---NA
GetCharCountJob-POYNXH\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-820.591 ns0.2576 ns0.2409 ns20.498 ns20.310 ns20.989 ns0.620.01---NA

With DOTNET_EnableAVX512F=0

MethodJobToolchainsizeencNameMeanErrorStdDevMedianMinMaxRatioRatioSDGen0Gen1AllocatedAlloc Ratio
GetBytesJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-815.685 ns0.2940 ns0.2750 ns15.791 ns15.234 ns16.202 ns1.000.000.0021-40 B1.00
GetBytesJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-815.482 ns0.0969 ns0.0809 ns15.458 ns15.378 ns15.633 ns0.990.020.0021-40 B1.00
GetCharsJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-822.264 ns0.4973 ns0.5528 ns22.087 ns21.686 ns23.379 ns1.000.000.0029-56 B1.00
GetCharsJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-823.657 ns0.2815 ns0.2495 ns23.623 ns23.312 ns24.073 ns1.060.030.0029-56 B1.00
GetByteCountJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-88.275 ns0.0317 ns0.0247 ns8.274 ns8.235 ns8.325 ns1.000.00---NA
GetByteCountJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-88.304 ns0.0380 ns0.0297 ns8.306 ns8.245 ns8.345 ns1.000.00---NA
GetCharCountJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-85.953 ns0.0696 ns0.0617 ns5.931 ns5.891 ns6.074 ns1.000.00---NA
GetCharCountJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe16utf-87.347 ns0.0277 ns0.0246 ns7.342 ns7.302 ns7.390 ns1.230.01---NA
GetBytesJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-816.420 ns0.3640 ns0.3226 ns16.284 ns16.096 ns17.034 ns1.000.000.0030-56 B1.00
GetBytesJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-816.727 ns0.1400 ns0.1241 ns16.713 ns16.554 ns16.938 ns1.020.020.0029-56 B1.00
GetCharsJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-824.938 ns0.4161 ns0.3689 ns24.880 ns24.519 ns25.590 ns1.000.000.0046-88 B1.00
GetCharsJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-824.797 ns0.1152 ns0.1021 ns24.805 ns24.644 ns24.927 ns0.990.020.0047-88 B1.00
GetByteCountJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-88.893 ns0.0236 ns0.0209 ns8.894 ns8.853 ns8.925 ns1.000.00---NA
GetByteCountJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-87.642 ns0.0171 ns0.0152 ns7.641 ns7.618 ns7.673 ns0.860.00---NA
GetCharCountJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-86.666 ns0.0187 ns0.0175 ns6.667 ns6.639 ns6.703 ns1.000.00---NA
GetCharCountJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe32utf-87.687 ns0.0064 ns0.0060 ns7.686 ns7.676 ns7.698 ns1.150.00---NA
GetBytesJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-828.484 ns0.2591 ns0.2297 ns28.462 ns28.234 ns28.920 ns1.000.000.0047-88 B1.00
GetBytesJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-830.190 ns0.5999 ns0.5009 ns30.452 ns29.091 ns30.659 ns1.060.020.0047-88 B1.00
GetCharsJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-829.352 ns0.2424 ns0.2268 ns29.315 ns28.931 ns29.652 ns1.000.000.0080-152 B1.00
GetCharsJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-828.814 ns0.2307 ns0.2045 ns28.849 ns28.504 ns29.228 ns0.980.010.0081-152 B1.00
GetByteCountJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-88.681 ns0.0169 ns0.0158 ns8.680 ns8.653 ns8.714 ns1.000.00---NA
GetByteCountJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-89.201 ns0.0190 ns0.0159 ns9.204 ns9.165 ns9.221 ns1.060.00---NA
GetCharCountJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-87.376 ns0.0084 ns0.0070 ns7.374 ns7.368 ns7.392 ns1.000.00---NA
GetCharCountJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe64utf-88.089 ns0.0232 ns0.0217 ns8.089 ns8.038 ns8.123 ns1.100.00---NA
GetBytesJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-836.537 ns0.1701 ns0.1421 ns36.568 ns36.284 ns36.775 ns1.000.000.0080-152 B1.00
GetBytesJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-835.399 ns0.1617 ns0.1434 ns35.347 ns35.154 ns35.641 ns0.970.000.0080-152 B1.00
GetCharsJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-836.593 ns0.4243 ns0.3968 ns36.610 ns35.943 ns37.308 ns1.000.000.0148-280 B1.00
GetCharsJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-836.775 ns0.3406 ns0.3020 ns36.863 ns36.344 ns37.137 ns1.000.010.0148-280 B1.00
GetByteCountJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-810.957 ns0.0113 ns0.0100 ns10.959 ns10.932 ns10.972 ns1.000.00---NA
GetByteCountJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-810.908 ns0.0235 ns0.0220 ns10.903 ns10.880 ns10.953 ns1.000.00---NA
GetCharCountJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-88.644 ns0.0455 ns0.0425 ns8.645 ns8.588 ns8.736 ns1.000.00---NA
GetCharCountJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe128utf-88.824 ns0.1000 ns0.0935 ns8.822 ns8.647 ns8.961 ns1.020.01---NA
GetBytesJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-852.601 ns0.3706 ns0.3285 ns52.589 ns52.028 ns53.098 ns1.000.000.0148-280 B1.00
GetBytesJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-849.847 ns0.3042 ns0.2697 ns49.815 ns49.474 ns50.335 ns0.950.010.0147-280 B1.00
GetCharsJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-854.972 ns0.5678 ns0.5033 ns54.919 ns54.226 ns56.047 ns1.000.000.0283-536 B1.00
GetCharsJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-854.261 ns0.9696 ns0.9070 ns54.289 ns52.871 ns56.101 ns0.990.020.0283-536 B1.00
GetByteCountJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-815.922 ns0.0803 ns0.0751 ns15.917 ns15.735 ns16.020 ns1.000.00---NA
GetByteCountJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-814.330 ns0.0253 ns0.0237 ns14.343 ns14.288 ns14.363 ns0.900.00---NA
GetCharCountJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-811.216 ns0.1034 ns0.0968 ns11.214 ns10.986 ns11.365 ns1.000.00---NA
GetCharCountJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe256utf-810.533 ns0.0370 ns0.0309 ns10.539 ns10.476 ns10.586 ns0.940.01---NA
GetBytesJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-899.951 ns0.7868 ns0.6974 ns100.088 ns98.710 ns101.068 ns1.000.000.0283-536 B1.00
GetBytesJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-880.361 ns0.5703 ns0.5056 ns80.284 ns79.564 ns81.469 ns0.800.010.0281-536 B1.00
GetCharsJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-893.390 ns1.0341 ns0.9673 ns93.122 ns92.216 ns95.289 ns1.000.000.0554-1048 B1.00
GetCharsJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-889.364 ns1.0377 ns0.9199 ns89.247 ns87.715 ns90.685 ns0.960.010.0557-1048 B1.00
GetByteCountJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-824.083 ns0.0269 ns0.0252 ns24.090 ns24.043 ns24.120 ns1.000.00---NA
GetByteCountJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-820.248 ns0.0847 ns0.0792 ns20.251 ns19.979 ns20.322 ns0.840.00---NA
GetCharCountJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-815.784 ns0.0404 ns0.0378 ns15.798 ns15.706 ns15.836 ns1.000.00---NA
GetCharCountJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe512utf-813.821 ns0.0650 ns0.0608 ns13.831 ns13.689 ns13.926 ns0.880.00---NA
GetBytesJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-8171.779 ns1.3070 ns1.1586 ns171.905 ns169.700 ns174.232 ns1.000.000.0551-1048 B1.00
GetBytesJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-8156.507 ns0.9721 ns0.8617 ns156.265 ns155.498 ns158.305 ns0.910.010.0555-1048 B1.00
GetCharsJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-8167.936 ns2.4062 ns2.1330 ns167.886 ns165.697 ns171.998 ns1.000.000.11000.00072072 B1.00
GetCharsJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-8156.658 ns1.2998 ns1.1523 ns157.029 ns154.017 ns158.111 ns0.930.010.10990.00062072 B1.00
GetByteCountJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-849.613 ns0.1716 ns0.1521 ns49.592 ns49.279 ns49.947 ns1.000.00---NA
GetByteCountJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-849.040 ns1.1058 ns1.2734 ns49.251 ns44.486 ns50.348 ns0.990.03---NA
GetCharCountJob-ZAMPDT\runtime-base\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-826.012 ns0.0622 ns0.0581 ns26.007 ns25.938 ns26.135 ns1.000.00---NA
GetCharCountJob-RVECRT\runtime\artifacts\bin\testhost\net8.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe1024utf-819.002 ns0.0659 ns0.0550 ns19.004 ns18.890 ns19.118 ns0.730.00---NA

@ghostghost added community-contribution Indicates that the PR has been added by a community member area-System.Numerics labels Jul 7, 2023
@ghost

ghost commented Jul 7, 2023

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/area-system-numerics
See info in area-owners.md if you want to be subscribed.

Issue Details

This PR lights up some code path in ASCII.Utility with Vector256/Vector512 code, namely, NarrowUtf16ToAscii, WidenAsciiToUtf16, GetIndexOfFirstNonAsciiChar, and GetIndexOfFirstNonAsciiByte.

For the GetIndexOfMethods, we have implemented the simpler, existing "default" code path but with the explicty VectorXX apis; for the Narrow/Widen methods, we have implemented the more complex SSE/Vector256 path but with the Vector256/Vector512 APIs. Right now, both are a slight tradeoff in terms of code complexity/performance.

We are open to adjusting the implementation style for either path. Perf numbers coming soon.

Author:anthonycanino
Assignees:-
Labels:

area-System.Numerics, community-contribution

Milestone:-

@anthonycanino

Copy link
Copy Markdown
ContributorAuthor

A rough summary of the results...

  1. We will see speedup with the Vector512 and Vector256 implementation on large data sizes.
  2. There is a lot of room to tune, particularly given the Vector512 and Vector256 paths do not use that much specialized intrinsics, though I think we want to favor this more general approach.

@anthonycanino

Copy link
Copy Markdown
ContributorAuthor

@dotnet/avx512-contrib can we get a review on this?

I checked the failures which look like they are related to a CPUID test, I don't think the changes would impact?

@tannergooding

Copy link
Copy Markdown
Member

CpuId failures are known and have a PR up to resolve them #88623

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why this instead of source.GetLower().StoreUnsafe(ref destination, elementOffset)?

Comment threadsrc/libraries/System.Private.CoreLib/src/System/Text/Ascii.Utility.cs Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why not this instead?

Suggested change
if(Unsafe.ReadUnaligned<Vector512<byte>>(pBuffer).ExtractMostSignificantBits()==0)
if(Vector512.Load(pBuffer).ExtractMostSignificantBits()==0)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We actually have an internal Vector512.Size that is a const for just these types of cases.

Comment threadsrc/libraries/System.Private.CoreLib/src/System/Text/Ascii.Utility.cs Outdated
uint SizeOfVectorInChars = (uint)Vector<ushort>.Count; // JIT will make this a const
uint SizeOfVectorInBytes = (uint)Vector<byte>.Count; // JIT will make this a const
uint SizeOfVector512InChars = (uint)Vector512<ushort>.Count; // JIT will make this a const
uint SizeOfVector512InBytes = (uint)Vector512.Size; // JIT will make this a const

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You should be able to use Vecto512.Size directly and have C# keep it a const instead.

It will make things a bit more readable and allow C# to constant fold some of the simple cases (e.g. ~(nuint)(SizeOfVector512InBytes - 1) itself will become constant foldable rather than forcing IL to emit ldloc; sub; conv.i; sub and then requiring the JIT to optimize that down.

/// Uses double instead of long to get a single instruction instead of storing temps on general porpose register (or stack)
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void StoreLowerUnsafe<T>(this Vector512<T> source, ref T destination, nuint elementOffset = 0)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same general question here as on the other. Why this helper rather than simply doing source.GetLower().StoreUnsafe(ref destination, elementOffset)

It looks like the right stuff happens for the former already and it avoids the JIT needing to do any inlining for it.


if (Vector512.IsHardwareAccelerated && bufferLength >= 2 * (uint)Vector512<byte>.Count)
{
uint SizeOfVector512InBytes = (uint)Vector512.Size; // JIT will make this a const

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same here and other places. If we use Vector512.Size directly, we get much simply and constant foldable IL, allowing the JIT to do less work.

Since Vector512.Size is itself a constant, we shouldn't need to insert extra casts anywhere. But if we did and it was a non-trivial number, it would be better to declare this as const uint SizeOfVector512InBytes instead so the same constant folding could still happen.

}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool VectorContainsNonAsciiChar(Vector256<byte> asciiVector)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need wrapper methods for this simple case?

Is there any reason it can't just be asciiVector != Vector256<byte>.Zero instead which allows ptest; jcc rather than movmsk, cmp; jcc?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I was doing this for code reuse/readability.

Would you prefer to just inline the function?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think inlining it manually in this case would be better.

The abstractions like this are generally helpful when we have more complex logic differing between platforms or when there is a high likelihood to need to identify and change the pattern for the same pattern repeatedly in the future.

In cases like this, where we're really just doing a trivial comparison check, I don't think the helper buys us much in terms of readability/maintainability and it does have drawbacks in the form of forcing the JIT to do more work to inline/optimize the code.

// Narrows two vectors of words [ w7 w6 w5 w4 w3 w2 w1 w0 ] and [ w7' w6' w5' w4' w3' w2' w1' w0' ]
// to a vector of bytes [ b7 ... b0 b7' ... b0'].

// prefer architecture specific intrinsic as they don't perform additional AND like Vector512.Narrow does

@tannergoodingtannergoodingJul 12, 2023

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this comment is out of sync. We're using the non architecture specific Narrow below.

Likewise, given we're just calling the xplat narrow, do we need this helper method or can we just call Narrow directly and avoid the need to inline?

Comment on lines +2192 to +2193
uint SizeOfVector256 = (uint)Vector256<byte>.Count;
nuint MaskOfAllBitsInVector256 = (nuint)(SizeOfVector256 - 1);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These can both be const, using Vector256.Size directly and declaring const nuint MaskOfAllBitsInVector256 for the latter.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same for the equivalent case in Intrinsified_512

1. turn some variables into explicitly specified const.
2. removed some helper functions and inlined them.
Debug.Assert((nuint)pBuffer % Vector512.Size == 0, "Vector read should be aligned.");
if (Vector512.LoadAligned(pBuffer).ExtractMostSignificantBits() != 0)
{
break; // found non-ASCII data

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If we're within the vectorized code path and see non-ASCII data, since we already have the return value of ExtractMostSignificantBits in a register somewhere, I wonder if it would make sense to tzcnt the result and return immediately rather than falling down the drain code path.

Not important for this review, just a random musing.


do
{
Debug.Assert((nuint)pBuffer % SizeOfVector512InChars == 0, "Vector read should be aligned.");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should read:

Debug.Assert((nuint)pBuffer%SizeOfVector512InBytes==0,"Vector read should be aligned.");

(Looks like this is a bug in the original GetIndexOfFirstNonAsciiChar_Default method as well.)

{
const uint SizeOfVector512InChars = Vector512.Size / sizeof(ushort);

Vector512<ushort> asciiMask = Vector512.Create((ushort) 0xFF80);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Unused local?

// We're going to get the best performance when we have aligned writes, so we'll take the
// hit of potentially unaligned reads in order to hit this sweet spot.

// pAsciiBuffer points to the start of the destination buffer, immediately before where we wrote

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Para should be updated: 0x10 bit, &pAsciiBuffer[SizeOfVector256 / 2], 16-byte write.

Looking back over the original comment this was copied from, I realize now what I originally wrote was word salad. 🙂 My comment wasn't intended to refer to the value stored at the referenced address, but rather the address itself. Basically, if you're trying to become 16-byte aligned, then one of the following must hold: (a) you can from your current position back up 7 or fewer bytes to achieve 16-byte alignment; or (b) you can write 8 bytes, bump the pointer, then back up 7 or fewer bytes to achieve 16-byte alignment.

For this method, since you're trying to become 32-byte aligned, those clauses become "15 or fewer bytes" and "you can write 16 bytes."

goto Finish;
}

// Turn the 32 ASCII chars we just read into 32 ASCII bytes, then copy it to the destination.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

16, not 32.


// First part was all ASCII, narrow and aligned write. Note we're only filling in the low half of the vector.

Debug.Assert(((nuint)pAsciiBuffer + currentOffsetInElements) % sizeof(ulong) == 0, "Destination should be ulong-aligned.");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
Debug.Assert(((nuint)pAsciiBuffer+currentOffsetInElements)%sizeof(ulong)==0,"Destination should be ulong-aligned.");
Debug.Assert(((nuint)pAsciiBuffer+currentOffsetInElements)%Vector128.Size==0,"Destination should be 128-bit-aligned.");

// We're going to get the best performance when we have aligned writes, so we'll take the
// hit of potentially unaligned reads in order to hit this sweet spot.

// pAsciiBuffer points to the start of the destination buffer, immediately before where we wrote

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same feedback as earlier: fix up comments.


// First part was all ASCII, narrow and aligned write. Note we're only filling in the low half of the vector.

Debug.Assert(((nuint)pAsciiBuffer + currentOffsetInElements) % sizeof(ulong) == 0, "Destination should be ulong-aligned.");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
Debug.Assert(((nuint)pAsciiBuffer+currentOffsetInElements)%sizeof(ulong)==0,"Destination should be ulong-aligned.");
Debug.Assert(((nuint)pAsciiBuffer+currentOffsetInElements)%Vector256.Size==0,"Destination should be 256-bit-aligned.");

break;
}

(Vector512<ushort> low, Vector512<ushort> upper) = Vector512.Widen(asciiVector);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: keep the same local variable names as the other blocks in this method.

@tannergooding

Copy link
Copy Markdown
Member

CC. @GrabYourPitchforks, looks like all your feedback has been addressed.

Comment on lines +104 to +108
if (Vector512.IsHardwareAccelerated || Vector256.IsHardwareAccelerated)
{
return GetIndexOfFirstNonAsciiByte_Vector(pBuffer, bufferLength);
}
else if (Sse2.IsSupported || (AdvSimd.IsSupported && BitConverter.IsLittleEndian))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

GetIndexOfFirstNonAsciiByte_Vector has a Vector128.IsHardwareAccelerated code path. We can't just rely on that and delete GetIndexOfFirstNonAsciiByte_Intrinsified?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

The Vector128 fallback path is slower than the (more complex) Intrinsified path (see #88532 (comment)).

@tannergooding
tannergooding merged commit a513676 into dotnet:mainJul 17, 2023
@lewinglewing mentioned this pull request Aug 1, 2023
@ghostghost locked as resolved and limited conversation to collaborators Aug 17, 2023
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Numericsavx512Related to the AVX-512 architecturecommunity-contributionIndicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@anthonycanino@tannergooding@GrabYourPitchforks@stephentoub@Ruihan-Yin