Performance matters!
1.19K subscribers
11 photos
2 files
63 links
Канал про SRE, Linux и производительность от Александра Лебедева (@alebsys).

Разбираю сбои, ускоряю системы, делюсь опытом.

🔹 Обо мне: alebedev.tech/about
🧑‍💻 Менторинг: alebedev.tech/mentoring
Download Telegram
CPU Utilization is Wrong by Brendan Gregg

B. Gregg показывает почему метрика утилизации %CPU может вводить в заблуждение - она включает в себя не только время затраченное на полезную работу CPU, но и ожидание обращения к памяти.

Как решение предлагается ориентироваться на показатель IPC (instructions per cycle), доступный в perf stat, atop, perf коллектор в node_exporter, etc.

tags: #linux #performance #metrics #cpu
👍31
How does hyperthreading work

Статья от performance engineer Peter Veentjer о технологии Hyper-Threading:

- архитектура CPU: frontend, backend, superscalar, pipelines, ...;
- за счет чего возможно использовать одно ядро для нескольких потоков;
- почему Hyper-Threading это не про быструю смену контекста.

Кстати, Peter является соавтором Performance Analysis and Tuning on Modern CPUs от Denis Bakhvalov.

#CPU #HT #performance
👍3
💥 Выступил на perfconf#10 с неделю назад💥

C докладом:

"Когда код идеален, но система тормозит. Скрытые враги производительности"

(немного пафосно звучит, но что поделать😉)

Рассказывал почтенной публике о влиянии TCP Retransmits и CPU Throttling на производительность приложений — как, зачем и что с этим делать.

Такой ликбез с небольшим deep dive в нюансы.

По ощущениям получилось вполне неплохо, и думаю, стоит повторять такие упражнения в будущем😊

По традиции — спасибо всем причастным! 🙌

P.S. Несколько фото и презентация прилагаются 📸💻

tags: #tcp #cpu
🔥24👍1
The Art of System Debugging — Decoding CPU Utilization

Или как баг в Java вызвал перегрузку CPU из-за избыточного чтения cgroupfs.

Заметка показывает, как eBPF помогает быстро находить сложные проблемы, и насколько труднее обходиться без него.

Статья интересна:

1. обилием реальных кейсов с использованием bcc утилит — всегда полезно увидеть, как коллеги исследуют системы с их помощью;

2. баги связанные со spinlock сложны для диагностики - создают ложное впечатление работы (высокий CPU System Time), хотя на деле система просто "активно ждет", перегружая процессор. Поэтому такие расследования всегда увлекательны.

В общем два в одном;)

tags: #cpu #troubleshooting
👍7
CPU Usage не так прост в интерпретации, как может показаться.

Сложность в том, что показатель включает в себя не только работу CPU, но и время обращения к памяти.

А так как память на порядки медленнее процессора, то на ожидание ответа может уходить 90%+ времени.

Чтобы точнее интерпретировать CPU Usage стоит присмотреться к показателю IPC (Instructions Per Cycle) - сколько процессор выполняет инструкций за один такт.

В условиях современных суперскалярных процессоров этот показатель может достигать четырех и более инструкций.
Хотя в реальных нагрузках значение IPC будет существенно меньше (0.7 - 1.5).

Таким образом высокий CPU Usage при низком IPC (<1) может говорить не о недостатке вычислительных мощностей (и это первое, что приходит в голову), а о проблемах с IO - недостаток кешей и/или их плохая локальность, слишком частое обращение к памяти и подобное.

Для лучшего погружения в тему читай:
* CPU Utilization is Wrong от Brendan Gregg;
* IPC is to CPU% What Milk is to Cinnamon Toast Crunch от Mark Dawson.

——————————————
P.S. получить значение IPC можно с помощью node_exporter через perf коллектор, например так:
sum(rate(node_perf_instructions_total{instance=~"$node",job="$job"}[$__rate_interval])) / sum(rate(node_perf_cpucycles_total{instance=~"$node",job="$job"}[$__rate_interval]))

———————————————
P.P.S. этот же пост, но на linkedin.

tags: #cpu #theory #linux
👍12🔥621
В нашей инфраструктуре мы давно используем PSI (Pressure Stall Information) для выявления перенасыщения (saturation) ресурсов: CPU, диск, память.

Есть мнение, что saturation — ключевой показатель, по которому легко понять состояние системы. Вокруг него построена методология USE Method.

PSI призван заменить Load Average, который не позволяет быстро и точно определять состояние системы.

Изначально PSI собирал данные per host — полезно, но шумно в контейнерных средах с множеством cgroup.

В Cgroup v2 появилась поддержка PSI для отдельных cgroup, а скоро cadvisor добавит сбор PSI по каждому контейнеру — вот тогда заживем!

P.S. Если будет запрос, могу в будущих заметках углубиться в детали. Дайте знать! 😊

tags: #cpu #k8s #metrics
👍59
На днях node-exporter зарелизил версию 1.9.0, где среди изменений мне бросилось в глаза:
- [FEATURE] pressure: add IRQ PSI metrics [#3048]


В обсуждении к MR был комментарий от @SuperQ:
Nice, it's too bad `CONFIG_IRQ_TIME_ACCOUNTING` is recommend to be off so very few people will benefit from this by default.


Что за рекомендации такие и кого они аффектят?

—————

Для начала чуть теории 📖

Обработчики прерываний бывает двух типов: аппаратные (Hard IRQ) и программные (SoftIRQ).

Hard IRQ вызываются устройствами (диск, клавиатура, сеть и т. д.) и немедленно обрабатываются процессором. Они могут прервать любой код, поэтому их обработку делают минимальной, чтобы быстрее освободить CPU для других задач.

SoftIRQ обрабатывает прерывания асинхронно в контексте ядра, не блокируя CPU. Поэтому ему отдают наиболее длительные этапы обработки.

В CPU Usage нагрузка от Hard IRQ отображается в %irq, а от SoftIRQ в %softirq.

—————

Теперь вернемся к изначальному вопросу.

Оказывается %irq отображается только при включённой опции CONFIG_IRQ_TIME_ACCOUNTING, иначе он всегда равен нулю.

В redhat-like дистрибутивах эта опция включена, тогда как в debian и им подобным её по умолчанию отключают!

# mpstat 1
Linux 5.10.0-20-amd64 02/18/2025 _x86_64_ (8 CPU)

11:28:51 PM CPU %usr %nice %sys %iowait %irq %soft %steal %idle
11:28:52 PM all 40.15 0.00 1.38 0.00 0.00 0.63 0.00 57.84
11:28:53 PM all 28.81 0.00 1.78 0.25 0.00 0.51 0.13 68.53
11:28:54 PM all 35.29 0.00 2.25 0.00 0.00 0.25 0.00 62.20
11:28:55 PM all 17.68 0.00 1.14 0.00 0.00 0.38 0.25 80.56
11:28:56 PM all 16.31 0.00 1.99 0.00 0.00 0.25 0.25 81.20

# mpstat -I ALL 1
11:32:53 PM CPU intr/s
11:32:54 PM all 18466.00
11:32:55 PM all 11983.00
11:32:56 PM all 14019.00


%irq
нулевой, хотя кол-во прерываний десятки тысяч.

А дальше самое интересное.

Если CONFIG_IRQ_TIME_ACCOUNTING отключена, нагрузка от Hard IRQ никуда не исчезнет (кэп🙂), а учитывается как:

1. если прерывание произошло в user mode, то время его обработки будет учтено как %user того процесса, который выполнялся до прерывания.
2. если прерывание произошло во время выполнения процесса в system mode, его обработка будет засчитана в %sys этого процесса.
3. если прерывание произошло во время выполнения фоновых задач ядра (kworker, ksoftirqd), то его обработка будет засчитана в %sys системы

В итоге точность анализа загрузки CPU снижается, что может вводить в заблуждение. Говорят, что погрешность может достигать 5–7%! А это хорошо бы проверить😉

Судя по документации ядра, опцию отключают из-за её небольшого влияния на производительность:
    Select this option to enable fine granularity task irq time
accounting. This is done by reading a timestamp on each
transitions between softirq and hardirq state, so there can be a
small performance impact.

If in doubt, say N here.


И это проверим:)

P.S. Подробнее, с примерами про подсчет irq читай в блоге Танел Подера.

#cpu #kernel
👍16🔥12
Об IPC
(конспект по книге Performance Analysis and Tuning on Modern CPUs)

Я уже писал о показателе Instructions Per Cycle (IPC) (например тут и тут). Сейчас разберём детали глубже.

Instruction Per Cycle (IPC) — это среднее количество инструкций, завершённых за один такт процессора:

IPC = Retired Instructions / Core Cycles

Определим ключевые понятия.

Инструкции делятся на executed и retired.

- Executed инструкции уже выполнены, но результат ещё не записан в память. Они могут выполняться вне порядка (out of order) и быть отменены, например, из-за miss branch prediction;

- Retired инструкции полностью завершены, то есть и выполнены и их результаты записаны (committed). Отменить их уже нельзя.

Executed напрямую не отслеживаются, а для retired есть отдельный счётчик:
perf stat -e instructions -- ./a.exe

2173414 instructions # 0.80 insn per cycle


Cycles (циклы) процессора бывают двух видов:
- core;
- reference.

Разница важна при динамическом изменении частоты процессора:
1. если CPU работает на штатной частоте: core = reference.
2. если CPU разогнан: core > reference.

Core Cycles отражают реальную текущую, когда Reference Cycles базовую (по паспорту) частоту процессора.
perf stat -e cycles,ref-cycles -- ./a.exe

43340884632 cycles # 3.97 GHz <= Core Cycles
37028245322 ref-cycles # 3.39 GHz <= Reference Cycles


Следовательно IPC показывает единицу A) выполненной B) полезной работы в текущий момент.

IPC не зависит от изменения тактовой частоты, так как всегда рассчитывается на один цикл.


Факторы, ограничивающие IPC
(перечислены в случайном порядке, список неполный):

- скорость памяти и cache misses;
- архитектура процессора: скалярность, загрузка слотов пайплайна;
- тип и сложность инструкций;
- branch misprediction (пенальти на ошибку по 10–25 ns);
- ...

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

На практике этот максимум недостижим: процессор может одновременно выполнять только определённые типы инструкций. Например, в 6-wide архитектуре за такт можно провести четыре операции сложения/вычитания, одну загрузку и одну запись, но не шесть загрузок одновременно.

to be continued...

#cpu #theory
👍16🔥9👎1