Сун Баохуа: анализ производительности Linux с точки зрения глобального представления Flame Graph

задняя часть Linux SVG Тенсент

Об авторе:Сун Баохуа, он имеет более чем 10-летний опыт разработки Linux. Он долгое время работал фронтовым инженером и системным архитектором на крупных предприятиях, писал много кода для Linux и отвечает за рецензирование кода других коллег на gerrit. Барри Сонг — активный разработчик Linux и один из самых активных разработчиков некоторых версий ядра (таких какrottweiler.net/articles/39…,rottweiler.net/articles/42…), также был мейнтейнером серии ARM SoC в основной ветке Linux.

Он также является автором книги «Десять самых продаваемых классических произведений» и «Десять лучших оригинальных продуктов» 2008 года «Подробное объяснение разработки драйверов устройств Linux» и переводчиком «Essential Linux Device Driver» от china-pub и других. к оценке продаж. В то же время он написал множество технических статей, является победителем конкурса 51CTO «Десять выдающихся ИТ-блогов» за 2012 год и экспертом-блогером 51CTO и CSDN. Он также увлекается проектами с открытым исходным кодом и разрабатывает LEP (Linux Easy Profiling,www.linuxep.com) и надеемся на участие и помощь большего числа людей.

Что такое флейм-граф

Flame Graph (Flame Graph) был изобретен гуру оптимизации производительности Linux Бренданом Греггом.В отличие от всех других методов трассировки и профилирования, Flame Graph рассматривает распределение времени с глобальной точки зрения.Он перечисляет все возможные стеки вызовов. Другие методы представления обычно перечисляют только один стек вызовов или неиерархическое распределение времени.

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

В качестве примера возьмем типичный график пламени на процессоре, который анализирует, на какие функции тратится процессорное время.

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

Процесс генерации графа пламени:

  1. Сначала проследите систему, чтобы получить данные профилирования системы.
  2. рисовать по сценарию

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

git clone https://github.com/brendangregg/FlameGraph

Пример графа пламени

Не много глупостей, начнем с самого простого примера. Talk is Cheap, покажите вам cde, код выглядит следующим образом:

c()
{
    for(int i=0;i<1000;i++);
}
b()
{
    for(int i=0;i<1000;i++);
    c();
}
a()
{
    for(int i=0;i<1000;i++);
    b();
}

Затем эти три функции появляются на графике пламени следующим образом:

2/3 времени a() тратится на b(), а 1/3 времени b() тратится на c(). Множество таких пламен a->b->c складываются вместе, образуя граф пламени.

Лучший способ понять флейм-граф по-прежнему — это рассмотреть реальный случай.Следующая программа создает 2 потока, обработчиками обоих потоков являются thread_fun(), а затем thread_fun() вызывает fun_a(), fun_b(), fun_c(). , а fun_a() вызывает fun_d():

/*
 * One example to demo flamegraph
 *
 * Copyright (c) Barry Song
 *
 * Licensed under GPLv2
 */

#include <pthread.h>

func_d()
{
    int i;
    for(i=0;i<50000;i++);
}

func_a()
{
    int i;
    for(i=0;i<100000;i++);
    func_d();
}

func_b()
{
    int i;
    for(i=0;i<200000;i++);
}

func_c()
{
    int i;
    for(i=0;i<300000;i++);
}

void* thread_fun(void* param)
{
    while(1) {
        int i;
        for(i=0;i<100000;i++);

        func_a();
        func_b();
        func_c();
    }
}

int main(void)
{
    pthread_t tid1,tid2;
    int ret;

    ret=pthread_create(&tid1,NULL,thread_fun,NULL);
    if(ret==-1){
        ...
    }

    ret=pthread_create(&tid2,NULL,thread_fun,NULL);
    ...

    if(pthread_join(tid1,NULL)!=0){
        ...
    }

    if(pthread_join(tid2,NULL)!=0){
        ...
    }

    return 0;
}

Давайте сначала рассмотрим недостатки неиспользования пламенных графов.

Если вы не используете график пламени, мы также можем использовать такие инструменты, как perf top, чтобы проанализировать, на что в основном тратится процессорное время:

$gcc exam.c -pthread
$./a.out&
$sudo perf top

Perf top отображает результаты следующим образом:

perf top вызывает fun_a(), fun_b(), fun_c(), fun_d(), thread_func(), код внутри этих функций сильно потребляет процессор, но ему не хватает глобального видения, мы не можем видеть глобальный вызов stack, а также не понимают связи между этими функциями. С пламенными графами дело обстоит иначе, мы можем сгенерировать пламенный граф с помощью следующей команды (запускать с привилегиями root):

perf record -F 99 -a -g -- sleep 60
perf script | ./stackcollapse-perf.pl > out.perf-folded
./flamegraph.pl out.perf-folded > perf-kernel.svg

Вышеприведенная программа фиксирует поведение системы в течение 60 секунд и, наконец, вызывает flamegraph.pl для создания пламенного графа perf-kernel.svg, который можно открыть с помощью инструмента для просмотра изображений.

Вышеприведенный график пламени показывает временное распределение thread_func(), func_a(), func_b(), fun_c() и func_d() в a.out.

Как видно из приведенного выше графика пламени, несмотря на то, что thread_func() вызывается двумя потоками, поскольку стек вызовов перед thread_func() одинаков, вызовы thread_func() двух потоков объединяются в один и тот же блок.

Читать далее

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

Например, в следующем графике показан пламя много причин Nginx, способных поступить в эту пропускную способность SEM_WAIT () семафора ожидания.

Изображение выше взято из «Введение в графики пламени вне ЦП» Ичуна Чжана (agentzh).

Для получения более подробной информации о графиках пламени и возможностях каждого из различных графиков пламени посетите:
Woohoo Брендан GRE Reform.com/flame graphs…

Эта статья взята из общедоступной учетной записи Linuxerr WeChat.

Связанное Чтение

Сун Баохуа: анализ и практика настройки производительности Linux

Xie Baoyou: глубокое понимание концепции RCU

Чжан Имин: краткая история eBPF (часть 2)


Эта статья была разрешена автором для публикации в сообществе Tencent Cloud Technology Community, укажите это при перепечатке.первоисточник

Исходная ссылка: https://cloud.tencent.com/community/article/934261?utm_source=juejin


Огромный технический практический опыт, все вОблачное сообщество Tencent