Информация об изменениях

Сообщение Re: Поддержка компиляторами профилирования и отладки кода от 07.06.2020 10:43

Изменено 07.06.2020 10:44 kov_serg

Re: Поддержка компиляторами профилирования и отладки кода
Здравствуйте, Евгений Музыченко, Вы писали:

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


ЕМ>При отладке нередко требуется история вызовов функций, которую приходится формировать вручную, включая в каждую функцию отладочные вызовы. Это и утомительно, и чревато ошибками (забыли вставить вызов, вызвали неправильно и т.п.).


ЕМ>В MS VC++ уже очень давно поддерживается автоматическая вставка вызова служебной функции _penter при входе в каждую функцию (/Gh) и _pexit — при выходе (/GH). По идее, фича чертовски мощная, но, как и многое другое у MS, реализована столь же чертовски убого — функцию, вызвавшую _penter/_pexit, можно определить только по адресу возврата, для этого нужно или каждый раз лезть в общую базу данных, или тупо складывать все вызовы в общий лог. Доступ к базе — сильные тормоза, синхронизация доступа к логу — тоже тормоза.

...
ЕМ>В каких-нибудь других реализациях C/C++ компиляторы поддерживают разумные средства профилирования/отладки?

  В MS VC++ есть PGO
// pgoautosweep.cpp
// Compile by using: cl /c /GL /W4 /EHsc /O2 pgoautosweep.cpp
// Link to instrument: link /LTCG /genprofile pgobootrun.lib pgoautosweep.obj
// Run to generate data: pgoautosweep
// Merge data by using command line pgomgr tool:
// pgomgr /merge pgoautosweep-func1!1.pgc pgoautosweep-func2!1.pgc pgoautosweep.pgd
// Link to optimize: link /LTCG /useprofile pgobootrun.lib pgoautosweep.obj

#include <iostream>
#include <windows.h>
#include <pgobootrun.h>

void func2(int count)
{
    std::cout << "hello from func2 " << count << std::endl;
    Sleep(2000);
}

void func1(int count)
{
    std::cout << "hello from func1 " << count << std::endl;
    Sleep(2000);
}

int main()
{
    int count = 10;
    while (count--)
    {
        if (count < 3)
            func2(count);
        else
        {
            func1(count);
            if (count == 3)
            {
                PgoAutoSweep("func1");
            }
        }
    }
    PgoAutoSweep("func2");
}

cl /c /GL /W4 /EHsc /O2 test-pgo.cpp
link /LTCG /genprofile pgobootrun.lib test-pgo.obj
test-pgo.exe
link /LTCG /useprofile pgobootrun.lib test-pgo.obj
А чем не устраивают шатные инструменты. Еще у интела и у нвиды есть.
Re: Поддержка компиляторами профилирования и отладки кода
Здравствуйте, Евгений Музыченко, Вы писали:

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


ЕМ>При отладке нередко требуется история вызовов функций, которую приходится формировать вручную, включая в каждую функцию отладочные вызовы. Это и утомительно, и чревато ошибками (забыли вставить вызов, вызвали неправильно и т.п.).


ЕМ>В MS VC++ уже очень давно поддерживается автоматическая вставка вызова служебной функции _penter при входе в каждую функцию (/Gh) и _pexit — при выходе (/GH). По идее, фича чертовски мощная, но, как и многое другое у MS, реализована столь же чертовски убого — функцию, вызвавшую _penter/_pexit, можно определить только по адресу возврата, для этого нужно или каждый раз лезть в общую базу данных, или тупо складывать все вызовы в общий лог. Доступ к базе — сильные тормоза, синхронизация доступа к логу — тоже тормоза.

...
ЕМ>В каких-нибудь других реализациях C/C++ компиляторы поддерживают разумные средства профилирования/отладки?

  В MS VC++ есть PGO
// pgoautosweep.cpp
// Compile by using: cl /c /GL /W4 /EHsc /O2 pgoautosweep.cpp
// Link to instrument: link /LTCG /genprofile pgobootrun.lib pgoautosweep.obj
// Run to generate data: pgoautosweep
// Merge data by using command line pgomgr tool:
// pgomgr /merge pgoautosweep-func1!1.pgc pgoautosweep-func2!1.pgc pgoautosweep.pgd
// Link to optimize: link /LTCG /useprofile pgobootrun.lib pgoautosweep.obj

#include <iostream>
#include <windows.h>
#include <pgobootrun.h>

void func2(int count)
{
    std::cout << "hello from func2 " << count << std::endl;
    Sleep(2000);
}

void func1(int count)
{
    std::cout << "hello from func1 " << count << std::endl;
    Sleep(2000);
}

int main()
{
    int count = 10;
    while (count--)
    {
        if (count < 3)
            func2(count);
        else
        {
            func1(count);
            if (count == 3)
            {
                PgoAutoSweep("func1");
            }
        }
    }
    PgoAutoSweep("func2");
}

cl /c /GL /W4 /EHsc /O2 test-pgo.cpp
link /LTCG /genprofile pgobootrun.lib test-pgo.obj
test-pgo.exe
link /LTCG /useprofile pgobootrun.lib test-pgo.obj
А чем не устраивают штатные инструменты. Еще интела и нвиды.