惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
博客园 - 三生石上(FineUI控件)
量子位
腾讯CDC
The Cloudflare Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
云风的 BLOG
云风的 BLOG
Vercel News
Vercel News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
L
LangChain Blog
aimingoo的专栏
aimingoo的专栏
The Hacker News
The Hacker News
T
The Exploit Database - CXSecurity.com
B
Blog
S
SegmentFault 最新的问题
P
Privacy & Cybersecurity Law Blog
T
Threatpost
博客园 - 聂微东
T
Tailwind CSS Blog
The Last Watchdog
The Last Watchdog
C
Check Point Blog
N
Netflix TechBlog - Medium
D
DataBreaches.Net
爱范儿
爱范儿
IT之家
IT之家
S
Secure Thoughts
M
MIT News - Artificial intelligence
NISL@THU
NISL@THU
C
Cisco Blogs
TaoSecurity Blog
TaoSecurity Blog
有赞技术团队
有赞技术团队
A
Arctic Wolf
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
P
Proofpoint News Feed
Spread Privacy
Spread Privacy
Schneier on Security
Schneier on Security
Simon Willison's Weblog
Simon Willison's Weblog
G
GRAHAM CLULEY
雷峰网
雷峰网
Project Zero
Project Zero
博客园 - Franky
H
Heimdal Security Blog
A
About on SuperTechFans
Security Latest
Security Latest
Webroot Blog
Webroot Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Hugging Face - Blog
Hugging Face - Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Руководство по анализу и настройке производительности для современных процессоров. Анонс книги
BHV_publishi · 2026-04-17 · via Все публикации подряд на Хабре

Руководство по анализу и настройке производительности для современных процессоров. Анонс книги

Время на прочтение10 мин

Охват и читатели5.3K

Перевод

Привет, Хабр.

Хотим поделиться с вами новостью о том, что завершаем более чем годичный фундаментальный проект - готовимся к выпуску русского издания знаменитой книги Дениса Бахвалова "Performance Analysis and Tuning on Modern CPUs: Learn to write fast software like a pro". Денис теснейшим образом взаимодействовал с нашими редакторами, мы составили глоссарий к русскому изданию и уверены, что книга на долгие годы станет де-факто главным пособием по оптимизации производительности CPU. Книга выросла из многочисленных практических исследований, которыми Денис занимается в компании "Intel", и в качестве анонса мы хотим предложить вам перевод статьи автора, которая вышла ещё в 2019 году и может считаться рассказом о том, как зародилась идея будущей книги. В тексте под катом содержатся многочисленные ссылки на статьи Дениса из блога https://easyperf.net/notes/, который также рекомендуем пристально изучить. Русскую книгу ждите в мае. Далее - от автора.

Говорят, что «производительность всё решает». Это было актуально десять лет назад и определённо актуально сейчас. Притом, что каждый день в мире генерируются всё новые и новые данные, и на их обработку требуются постоянно растущие вычислительные мощности.

Так сложилось, что некоторые поставщики программного обеспечения предпочитают дождаться, пока появится новое поколение аппаратного обеспечения, на котором их приложения станут работать быстрее — таким образом, не тратить человеческие ресурсы на улучшение написанного кода. Но в настоящее время уже не наблюдается, чтобы каждое новое поколение аппаратного обеспечения давало значительный рост производительности. Поэтому требуется уделять больше внимания тому, насколько быстро ваш код выполняется на самом деле.

Что такое анализ производительности

По моему опыту, многие люди оптимизируют свои приложения, опираясь на собственную интуицию. Обычно это приводит к спонтанным правкам то тут, то там и не оказывает реального влияния на производительность приложения. Я считаю, что умение находить, где именно требуется внести такие правки, должно основываться на тщательном анализе производительности, а не на интуиции. Но даже в таком случае это лишь половина задачи. Вторая половина — это грамотно исправить код.

Часто бывает так, что достаточно изменить в программе всего одну строку кода — и производительность программы возрастает вдвое! Суть анализа производительности именно в том, чтобы найти и исправить эту строку! Упускать такие возможности слишком расточительно.

Зачем нужно анализировать производительность?

Количество ядер в современных ЦП растёт из года в год. На момент подготовки этой статьи в продаже были серверные процессоры высшей категории, каждый из которых оснащён более чем 100 логическими ядрами. Это очень впечатляет, но не означает, что больше нет необходимости заботиться о производительности. Очень часто бывает так, что производительность приложения не улучшится, если выделить на его работу больше ядер. Если вы в будущем собираетесь масштабировать ваш продукт, то критически важно понимать, почему это происходит, и как с этим справиться. Если вы не умеете правильно анализировать производительность и настраивать её, то будете напрасно терять значительную вычислительную мощность.

Хочется спросить: так почему же аппаратное обеспечение не решает всех наших проблем? Почему их не решают компиляторы? Если коротко — они, в самом деле, помогают, но всех проблем решить не могут. Современные ЦП невероятно быстро выполняют инструкции, но ничего не могут поделать, если применяемые для решения задачи инструкции неоптимальны или даже избыточны. Обычно компиляторы применяют массу эвристик, которые, как правило, работают, но всех пограничных случаев не покрывают — покрыть их попросту невозможно.

В такой ситуации мы, занимаясь поддержкой нашего кода, более не можем винить компилятор или железо за то, что они не справляются с той работой по повышению производительности, которую должны делать мы сами. Уверен, что аккуратный анализ производительности и умение её настраивать будут ценными навыками на протяжении многих ближайших лет.

Кому нужно анализировать производительность?

Современные процессоры очень сложно устроены. Однако расслабьтесь — нет в мире никого, кто во всех деталях понимал бы, как именно работает современный многоядерный процессор. К сожалению, это же означает, что и сама тема анализа производительности весьма сложна, полна всевозможных незнакомых метрик и терминов. Вот почему я всегда стремлюсь обо всём рассказывать просто. Думаю, можно доступным языком рассказать и об искусстве анализа производительности.

Ниже в этой статье я рассмотрю 4 столпа, на которых базируется эта тема:

  1. Как сконфигурировать машину и правильно измерять производительность?

  2. Какие возможности для анализа производительности предоставляются на уровне аппаратного обеспечения, и как с ним взаимодействуют софтверные инструменты?

  3. Важнейшие методологии анализа производительности.

  4. Как подходить к решению типичных проблем с производительностью.

Если хотите — считайте это нашим путевым маршрутом.

Как честно измерять производительность

На аппаратном и программном уровне реализовано множество различных возможностей, призванных как по волшебству повышать производительность. Но поведение некоторых из этих фич является недетерминированным. Возьмём, к примеру, возможность турбоускорения (turbo boost): если на «неразогретом» процессоре запустить один за другим два прогона, то первый прогон какое-то время, вероятно, будет работать в режиме повышенной тактовой частоты (то есть, быстрее), а второй — на базовой частоте, то есть, турбоускорение его не затронет. Вот одна из причин, по которым результаты могут варьироваться.

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

Профилирование приложений

Пожалуй, древнейший известный метод анализа производительности — это инструментирование кода. Мы этим постоянно занимаемся. Помните, как вам доводилось добавлять printf в начале функции, просто, чтобы подсчитать, сколько раз вызывается функция? О, я тоже так делал. Это простейший и при этом самый точный и развёрнутый способ проанализировать производительность приложения. Но у инструментирования кода есть и серьёзные недостатки. В частности, большие накладные расходы и необходимость перекомпилировать приложение всякий раз, когда мы захотим проделать с ним что-то новое. В наши дни немногие люди занимаются инструментированием кода вручную.

Шли годы, разрабатывались новые методы анализа производительности. Один из них основан на использовании прерываний мониторинга производительности (PMI) и называется «профилированием». Проще всего трактовать его так. Если вы, работая с отладчиком, будете каждую секунду приостанавливать программу и записывать, где именно вы остановились, то получите выборку (совокупность образцов). Если затем агрегировать все образцы и построить гистограмму, то вы увидите, на что именно программа тратит больше всего времени. Это предельно упрощённое описание, позволяющее составить впечатление, что именно делают инструменты профилирования, но идея похожа. Есть автоматизированные инструменты, например,  “perf” в Linux и “Intel Vtune”, записывающие тысячи прерываний (образцов) в секунду, пока работает ваша программа, а затем обобщающие информацию о них.

Базовый компонент, благодаря которому это становится возможным — это счётчик мониторинга производительности (PMC). С его помощью можно подсчитывать разные события. Например, при помощи PMC можно сосчитать, сколько ассемблерных инструкций было выполнено с момента запуска приложения. То есть, этот инструмент можно сконфигурировать так, чтобы каждая выполняемая на аппаратной платформе ассемблерная инструкция увеличивала значение этого счётчика на единицу. Базовое введение в работу блоков измерения производительности (PMU) сделано в этой статье.

Для целей профилирования PMC можно использовать несколько более хитроумным образом. Предположим, что ЦП работает на частоте 1 Ггц, то есть, выполняет 10⁹ тактов в секунду. Чтобы приостанавливать программу всякий раз после каждого из миллиона (10⁶) тактов (то есть, получает 1000 образцов в секунду), проделаем следующие шаги:

1. устанавливаем счётчик в значение -1'000'000
2. Включаем подсчёт
3. Дожидаемся переполнения, о котором нам сообщит процессор 
3.1. Когда переполнение произойдёт — отключаем подсчёт 
3.2. Отловим PMI
3.3. Внутри обработчика прерываний отловим указатель на инструкцию (IP).
4. Возвращаемся к шагу 1

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

О том, как в основе своей построена работа инструмента “perf” в Linux рассказано в этой статье.

В наше время профилирование — наиболее популярный, но не единственный способ наблюдения за производительностью на аппаратном уровне. Если вам интересно, какие другие продвинутые возможности профилирования предоставляются в современных ЦП, и как с ними работать — можете почитать  этуэту и эту статьи.

Наконец, при анализе производительности вам может очень пригодиться такая вещь как трассировка. Если вам знакомы инструменты Linux strace/ftrace, то вас это не должно удивлять. Конечно, при мониторинге, основанном на прерываниях, мы по определению будем пропускать значительное количество интересующих нас событий — а при трассировке мы отслеживаем их все. Можно трактовать это как гибридное решение по инструментированию кода с применением мониторинга на основе прерываний. Применяя трассировку, мы получаем достоинства обоих этих методов. Трассировка обходится не так дорого как инструментирование, но позволяет собирать массу информации о выполнении программы. Возможности отслеживания работы ядер в современных ЦП позволяют отследить практически каждую отдельную ассемблерную инструкцию ценой относительно небольших издержек. Подробнее о трассировке процессора (PT) рассказано здесь.

Методологии анализа производительности

В самом незатейливом случае всё, что вам потребуется — выявить в приложении «горячие точки». Возможно, вы заметите в коде участок, который не должен выполняться настолько долго, как он фактически выполняется. В таком случае можно реализовать высокоуровневое преобразование, которое позволит оптимизировать среду выполнения. Например, дело может быть в том, что в программе делается какая-то избыточная работа, без которой в определённых ситуациях можно обойтись.

Правда, когда все легкодоступные (высокоуровневые) оптимизации уже реализованы, а вам всё ещё нужны дополнительные улучшения, чтобы соответствовать предъявленным требованиям, то нужно знать не только о таких «горячих точках», но и другую информацию. Именно эту часть работы можно охарактеризовать как «настройку» (низкоуровневые оптимизации). В современных ЦП поддерживается и такая тонкая настройка.

Важно понимать, что, даже если бы ЦП мог предоставлять всемерную поддержку — он не совершит чудес, если в приложении есть серьёзные проблемы с производительностью. Например, если в программе применяется сортировка пузырьком, то нет никакого смысла даже заглядывать в продвинутые метрики производительности ЦП — сначала нужно исправить ключевую проблему.

Теперь давайте разберём, почему в низкоуровневых оптимизациях нет ничего таинственного. Низкоуровневые преобразования обычно выполняет компилятор и, как правило, они нацелены на конкретную платформу, на которой может работать код. Обычно это не задача программиста, но программист может вручную существенно улучшить время выполнения программы. Вот хорошо известные примеры таких преобразований:

Существует и много других методологий анализа производительности, но немногие из них надёжны и хорошо формализованы. Можно не усложнять и просто профилировать приложение, пытаясь осмыслить его горячие точки, а на основе этой информации попытаться что-то выиграть. Часто это приводит к бессистемным экспериментам, в результате которых при определённом везении можно чего-то добиться. Но вообще, если вы занимаетесь микроархитектурными оптимизациями (читай:низкоуровневым анализом производительности), то лучше опираться на более надёжные и проверенные методы.

Одна из таких методологий называется Метод нисходящего анализа микроархитектуры (TMAM). Это процесс итерационного выявления источника проблемы — именно той точки в коде, где она возникает, с последующим исправлением. Процесс построен таким образом, чтобы можно было охарактеризовать узкое место, найденное в приложении, и отнести это бутылочное горлышко к одной из четырёх категорий: «Выключение», «Неверное предположение», «Связано с фронтендом» и «Связано с бэкендом». После этой классификации начинаем углубляться в конкретную категорию, чтобы найти именно то событие, которое ограничивает производительность приложения. Когда, наконец, однозначно определено, с каким именно узким местом мы имеем дело, нужно перезапустить приложение и найти места, в которых инициируются события именно такого типа. Устранив проблему, вы вновь возвращаетесь к процессу  TMAM и повторяете его, пока не добьётесь такой производительности, к которой стремитесь.

Анализ многопоточных приложений

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

Вот другой пример: имея дело с однопоточным приложением, можно оптимизировать всего одну часть программы — и, как правило, это положительно скажется на производительности. Но в случае с многопоточными приложениями всё не так однозначно. Может быть один поток, выполняющий какую-то тяжеловесную операцию и действующий как барьер для всех остальных. То есть, пусть даже большинство потоков уже справилось со своей работой, процесс не закончится до тех пор, пока остаётся один поток, который всё ещё занят делом.

Но самая важная и сложная составляющая многопоточных приложений — это блокировки. Критически важно наладить эффективную коммуникацию между потоками, чтобы полностью использовать всю вычислительную мощность системы. Блокировки подобны функциям в том, что к некоторым из них обращаются чаще, чем к другим. Поэтому важно выявить наиболее активные блокировки и сосредоточиться на них. Кроме того, здесь возникают такие интересные эффекты как ложное разделение кэша, не происходящие в однопоточном мире.

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

Примеры настройки

Как показывает практика, ~90% всех оптимизаций можно выполнить в исходном коде приложения, не затрагивая окружения — компилятор, настройки операционной системы, т.д. Если вы решите овладеть искусством настройки производительности, то лучше познакомиться с рецептами, позволяющими решать типичные проблемы из этой области.

В начале 2019 года я стал делать челленджи, решая которые, можно напрактиковаться в настройке имеющихся бенчмарков. На этих примерах можно найти возможности оптимизации, причём, в заданиях подробно описано, как их находить. Можете пользоваться ими как шаблонами для оптимизации вашего приложения.

Надеюсь, эта статья вам пригодится и буду очень рад, если она поможет разработчикам оптимизировать код.