Сравнение C++ кода с ассемблерным на x86_64 в окне IDE.

Когда компиляторы удивляют

Компиляторы то и дело удивляют меня очень хитрыми трюками. Когда я впервые увидел эту оптимизацию, то едва смог поверить в её реальность. Я изучал оптимизацию циклов и написал вот такую простую функцию, суммирующую все числа до заданного значения:

88a6d27ce56306925ed4573ee64316b5

Compiler Explorer

aoco.compiler-explorer.com

Пока всё вполне привычно: GCC выполнил предварительные проверки, затем попал в цикл, который суммирует числа при помощи lea (мы уже видели такое раньше). Но приглядевшись к циклу, мы найдём нечто необычное:

.L3: lea edx, [rdx+1+rax*2] ; result = result + 1 + x*2 add eax, 2 ; x += 2 cmp edi, eax ; x != value jne .L3 ; продолжаем цикл

Умный компилятор понял, что может обрабатывать по два числа1 за раз благодаря тому что увидел суммирование x и x + 1, что эквивалентно сложению x*2 + 1. Думаю, вы согласитесь, что это очень разумное поведение!

Если повысить уровень оптимизатора до -O3 , то можно увидеть, что компилятор прилагает ещё больше усилий к векторизации цикла при помощи параллельных сложений. Тоже очень умное действие.

С компилятором GCC мы разобрались. Давайте посмотрим, что с нашим кодом делает clang:

9821e5967674f034f75c0f07dc38da6c

Compiler Explorer

aoco.compiler-explorer.com

И вот на этом моменте я чуть не упал со стула: цикла нет! Clang проверяет, положительно ли value, и если да, то выполняет следующее:

lea eax, [rdi — 1] ; eax = value — 1 lea ecx, [rdi — 2] ; ecx = value — 2 imul rcx, rax ; rcx = (value — 1) * (value — 2) shr rcx ; rcx >>= 1 lea eax, [rdi + rcx] ; eax = value + rcx dec eax ; —eax ret

Для меня было не совсем очевидно, что же, чёрт побери, здесь происходит. Но если немного разобраться с математикой, то становится понятно, что это эквивалентно такой записи:

v + ((v — 1)(v — 2) / 2) — 1;

Раскроем скобки:

v + (v? — 2v — v + 2) / 2 — 1

Немного изменим порядок:

(v? — 3v + 2) / 2 + (v — 1)

Умножаем (v — 1) на 2 / 2:

(v? — 3v + 2) / 2 + (2v — 2)/2

Объединяем их и сокращаем:

(v? — v) / 2

Упростив и вынеся за с??обки, получим v(v — 1) / 2 , то есть решение в аналитическом виде «суммы целых чисел»! Поистине великолепно2 — мы выполнили переход написанного в коде от алгоритма O(n) к O(1)!

Я обожаю то, что, несмотря на более чем двадцатилетний опыт работы с компиляторами, они по-прежнему удивляют и радуют меня. Годы опыта и труда, вложенные в совершенствование компиляторов, впечатляют и вдохновляют.

  1. Часть изначального кода выполняет проверку на чётность/нечётность, и учитывает их.

  2. Почему компилятор генерирует именно такую последовательность, а не чуть более простую? Думаю, частично это вызвано необходимостью избегать переполнения в случаях, когда иначе бы возникло переполнение; это просто побочный эффект того, как clang отслеживает и выводит индуктивные переменные. Впрочем, наверняка я этого не знаю.

Источник: habr.com

Источник: ai-news.ru

✅ Найденные теги: Когда, Компиляторы, новости, Удивление

ОСТАВЬТЕ СВОЙ КОММЕНТАРИЙ

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Каталог бесплатных опенсорс-решений, которые можно развернуть локально и забыть о подписках

галерея

Фото сгенерированных лиц: исследование показывает, что люди не могут отличить настоящие лица от сгенерированных
Нейросети построили капитализм за трое суток: 100 агентов Claude заперли…
Скетч: цифровой осьминог и виртуальный мир внутри компьютера с человечком.
Сцена с жестами пальцами, где один жест символизирует "VPN", а другой "KHP".
‼️Paramount купила Warner Bros. Discovery — сумма сделки составила безумные…
Скриншот репозитория GitHub "Claude Scientific Skills" AI для научных исследований.
Структура эффективного запроса Claude с элементами задачи, контекста и референса.
Эскиз и готовая веб-страница платформы для AI-дизайна в современном темном режиме.
ideipro logotyp
Image Not Found
Звёздное небо с галактиками и туманностями, космос, Вселенная, астрофотография.

Система оповещения обсерватории Рубина отправила 800 000 сигналов в первую ночь наблюдений.

Астрономы будут получать оповещения о небесных явлениях в течение нескольких минут после их обнаружения. Теренс О'Брайен, редактор раздела «Выходные». Публикации этого автора будут добавляться в вашу ежедневную рассылку по электронной почте и в ленту новостей на главной…

Мар 2, 2026
Женщина с длинными тёмными волосами в синем свете, нейтральный фон.

Расследование в отношении 61-фунтовой машины, которая «пожирает» пластик и выплевывает кирпичи.

Обзор компактного пресса для мягкого пластика Clear Drop — и что будет дальше. Шон Холлистер, старший редактор Публикации этого автора будут добавляться в вашу ежедневную рассылку по электронной почте и в ленту новостей на главной странице вашего…

Мар 2, 2026
Черный углеродное волокно с текстурой плетения, отражающий свет.

Материал будущего: как работает «бессмертный» композит

Учёные из Университета штата Северная Каролина представили композит нового поколения, способный самостоятельно восстанавливаться после серьёзных повреждений.  Речь идёт о модифицированном армированном волокном полимере (FRP), который не просто сохраняет прочность при малом весе, но и способен «залечивать» внутренние…

Мар 2, 2026
Круглый экран с изображением замка и горы, рядом электронная плата.

Круглый дисплей Waveshare для креативных проектов

Круглый 7-дюймовый сенсорный дисплей от Waveshare создан для разработчиков и дизайнеров, которым нужен нестандартный экран.  Это IPS-панель с разрешением 1 080×1 080 пикселей, поддержкой 10-точечного ёмкостного сенсора, оптической склейкой и защитным закалённым стеклом, выполненная в круглом форм-факторе.…

Мар 2, 2026

Впишите свой почтовый адрес и мы будем присылать вам на почту самые свежие новости в числе самых первых