
Бенчмаркая Sum: ускорил циклом — замедлил в ×4,7
Geronom 26 минут назад Бенчмаркая Sum: ускорил циклом — замедлил в ×4,7 Средний 8 мин 403 C# * .NET * Программирование * Аналитика Уважаемые читатели, в этой статье я хочу рассказать о том, что происходит внутри...
<5 — 2026'da uzaya kaç SpaceX Starship fırlatması ulaşacak?
Значимый прорыв формирует отрасль ИИ: Geronom 26 минут назад Бенчмаркая Sum: ускорил циклом — замедлил в ×4,7 Средний 8 мин 403 C# * . NET * Программирование * Аналитика Уважаемые читатели, в этой статье я хочу рассказать о том, что происходит внутри values. Sum() в современном .
NET — там нашлись векторные инструкции, контроль переполнения и список процессоров, которым рантайм намеренно ограничивает ширину вектора, — и представить свои выводы. В прошлых статьях серии самописные циклы уже проигрывали BCL в поиске по строке, JIT сам выкидывал проверки границ, а foreach прятал аллокации. Тут случай интереснее: values.
Технические детали
Sum() — это LINQ, который при оптимизации первым делом меняют на цикл. Как оказалось, на суммировании массива LINQ обгоняет обычный for! Не потому что цикл плохой, а потому что с .
NET 8 Sum() на int и long векторизован (PR dotnet/runtime #84519, автор brantburnett, ревью tannergooding), а RyuJIT произвольный цикл не векторизует: в моих листингах SumFor остаётся скаляром на всех рантаймах вплоть до . NET 11, запрос на автовекторизацию висит с 2019 (issue #12466). Будет 3 истории:LINQ обгоняет цикл — как одна строка получила vpaddd, а обычный for остался со скалярным add, и какой получилась разница на четырёх машинах;гарантии под капотом — Sum() обязан кидать OverflowException, и векторному коду приходится добавлять отдельные инструкции контроля переполнения; заодно официальный breaking change: порядок сложения изменился, и OverflowException теперь срабатывает на других данных;AVX-512, который .
NET прячет — почему один Xeon получает 512 бит по флагу, а второму рантайм режет ширину намеренно, и что дало снятие запрета. Код, скрипты снятия дизасма и готовые прогоны всех машин — в репозитории LinqSumProof. Тесты гонялись на четырёх машинах:№CPUЯдра/потокиЧастотаВектораL3№1AMD Ryzen 9 5950X16 / 323,4 ГГц базовых и до 4,9 в турбоAVX264 МБ№2Intel Core i9-10900KF10 / 203,7 ГГц базовых и до 5,3 в турбоAVX220 МБ№32 × Intel Xeon Silver 4314 (Ice Lake)2×16 / 642,4 ГГц базовых и до 3,4 в турбоAVX-51224 МБ на сокет№4Intel Xeon W-2255 (Cascade Lake)10 / 203,7 ГГц базовых и до 4,5 в турбо (4,7 с Turbo Boost Max 3.
Отраслевые последствия
0)AVX-51219,25 МБИстория 1. LINQ обгоняет циклОбычный цикл: public static int SumFor(int values) { int sum = 0; for (int i = 0; i < values. Length; i++) { sum += values; } return sum; }Вызов Sum(): public static int SumLinq(int values) => values.
Sum();Внутри Sum() с . NET 8 живёт проверка: если источник — массив или List, он превращается в ReadOnlySpan и уходит в векторный метод SumSignedIntegersVectorized (Sum. cs в исходниках рантайма).
Смотрим машинный код. Цикл — скаляр, одно сложение за итерацию (здесь и дальше листинги сокращены до смысловых строк):; SumFor, i9-10900KF, . NET 10, disasm_net10.
Этот прогресс даёт важные сигналы о будущем отрасли, и технологический мир внимательно наблюдает.




