“Амперметр”
От: Khimik  
Дата: 03.06.19 19:28
Оценка: -1
Я раньше немного пользовался AQTime для Delphi, в частности для оптимизации кода. AQTime в теории должен показывать участки кода, которые надо оптимизировать. Но я не очень верю в этот подход, потому что для измерения скорости нужно ставить в коде счётчики, а счётчики сами отнимают ресурсы. Мне интуитивно кажется что такие вещи, как работа счётчиков, необходимо контролировать самому.
Поэтому я написал такой объект на Delphi:

type
  TSpeedManager=record
    FSession:record
      CurTagsCount:integer;
      AllTagsCount:integer;
      Tags:array[0..maxsessiontagscount-1] of record
        RunsCount:int64;
        RunsSumTimeMs:int64;
        LastTime:longword;
      end;
      SessionActivationTime:longword;
      SessionFinalizationTime:longword;
    end;
    FSessionFinalized:boolean;
    FReport:tstringlist;

    procedure WriteSessionReport;
    procedure SaveReportToFile;
    procedure StartSession(alltagscount:integer);
    procedure FinalizeSession;
    procedure PlaceTag(tagnum:integer);
    procedure Initialize;
    procedure Finalize;
  end;

var
  ProjectSpeedManager:TSpeedManager;


В моём коде этот объект используется, например, вот так:

function TLinearTrianlesPlaneUnpackedModel.CalculateQPart(pointx,pointy:integer):double;
  begin
    projectspeedmanager.StartSession(4);
    projectspeedmanager.PlaceTag(1);
    result:=CalculateQPartR(pointx,pointy)*(1-FKDeriv2);
    projectspeedmanager.PlaceTag(2);
    result:=result+CalculateQPartDN(pointx,pointy)*FKDeriv2;
    projectspeedmanager.PlaceTag(3);
    projectspeedmanager.FinalizeSession;
  end;


Это код для МНК-минимизации некоего функционала; функционал состоит из двух слагаемых, соответственно считается двумя разными функциями. В данном участке считается не сам функционал, а его градиент по конкретному параметру, и градиент также состоит из двух слагаемых.
Когда программа отработала, projectspeedmanager сохранил текстовой файл отчёт, из которого я узнал, что код между тагами 1 и 2 занял 68% всего времени, а код между тэгами 2 и 3 – 31% времени. Соответственно я теперь знаю, что для оптимизации нужно прежде всего ускорить функцию CalculateQPartR, и в ней я также могу разместить тэги в разных её участках, чтобы узнать какие участки самые проблемные, потом разместить тэги и в них и т.д. Также projectspeedmanager сообщил мне, что выполнение всего кода между StartSession и FinalizeSession заняло 82% всего времени работы программы, точнее кода, который вызывал эту функцию CalculateQPartR (я и сам уже знал что функция CalculateQPartR лимитирующая, но на всякий случай полезно такие вещи проверять).
Это пока работает скорее в самых простых случаях, а мне придётся ещё приспосабливать мой амперметр для более сложных вариантов, например когда часть счётчиков находится внутри цикла, а часть за его пределами. Возможно тут будут нужны какие-то вложенные сессии, каждая со своим набором счётчиков.
В дальнейшем, возможно, потребуется сделать ещё вот что: “прокалибровать” мой амперметр, чтобы знать, сколько времени отнимает вызов счётчиков, и учесть это в пересчёте процентов, отданных каждому участку кода.
Можете подсказать, как аналогичный объект будет выглядеть на C++?
"Ты должен сделать добро из зла, потому что его больше не из чего сделать". АБ Стругацкие.
Re: “Амперметр”
От: kov_serg Россия  
Дата: 03.06.19 21:31
Оценка:
Здравствуйте, Khimik, Вы писали:

K> Можете подсказать, как аналогичный объект будет выглядеть на C++?

http://icl.cs.utk.edu/papi
http://www.intel.com/software/pcm
Re: “Амперметр”
От: bnk СССР http://unmanagedvisio.com/
Дата: 03.06.19 21:41
Оценка:
Здравствуйте, Khimik, Вы писали:

K>Но я не очень верю в этот подход


А есть какие-то конкретные основания для недоверия AQTime, или это на уровне суеверий?

K>В дальнейшем, возможно, потребуется сделать ещё вот что: “прокалибровать” мой амперметр, чтобы знать, сколько времени отнимает вызов счётчиков, и учесть это в пересчёте процентов, отданных каждому участку кода.


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

K>Можете подсказать, как аналогичный объект будет выглядеть на C++?


Ты же кажется что-то вычисляешь-оптимизируешь? На C++ это в идеале был бы вызов какой-нибудь численной библиотеки на CUDA/OpenCL, не?
В чем особо смысл оптимизировать такой вот велосипед, если запуск на числодробилке может дать прирост производительности сразу на порядки?
Если ты про то, как время замерять, в современном C++ это вроде бы std::chrono::high_resolution_clock
Re: “Амперметр”
От: ylem  
Дата: 04.06.19 06:50
Оценка: +1
Гуглите про "sample vs instrumental profiling"
Re[2]: “Амперметр”
От: Khimik  
Дата: 04.06.19 08:49
Оценка:
bnk>Ты же кажется что-то вычисляешь-оптимизируешь? На C++ это в идеале был бы вызов какой-нибудь численной библиотеки на CUDA/OpenCL, не?
bnk>В чем особо смысл оптимизировать такой вот велосипед, если запуск на числодробилке может дать прирост производительности сразу на порядки?
bnk>Если ты про то, как время замерять, в современном C++ это вроде бы std::chrono::high_resolution_clock

А что такое "числобробилка", можно чуть подробнее.
А вообще мне кажется, вы никогда не занимались оптимизацией алгоритмов.
"Ты должен сделать добро из зла, потому что его больше не из чего сделать". АБ Стругацкие.
Re[3]: “Амперметр”
От: bnk СССР http://unmanagedvisio.com/
Дата: 04.06.19 09:40
Оценка:
Здравствуйте, Khimik, Вы писали:

bnk>>Ты же кажется что-то вычисляешь-оптимизируешь? На C++ это в идеале был бы вызов какой-нибудь численной библиотеки на CUDA/OpenCL, не?

bnk>>В чем особо смысл оптимизировать такой вот велосипед, если запуск на числодробилке может дать прирост производительности сразу на порядки?
bnk>>Если ты про то, как время замерять, в современном C++ это вроде бы std::chrono::high_resolution_clock

K>А что такое "числобробилка", можно чуть подробнее.


Я имел в виду, CUDA/OpenCL работают на GPU, там же у тебя будет сотни-тысячи потоков обработки вместо нескольких,
или даже если на CPU, всякие там хитрые потоковые иниструкции используют.
Не уверен, что можно приблизиться к этой производительности, тасуя строки на дельфи.

K>А вообще мне кажется, вы никогда не занимались оптимизацией алгоритмов.


Ну в какой-то степени занимался, но не так чтобы профессионально (обработка картинок в матлабе например сойдет?)
AQTime тоже использовал, лет 15 назад, мне показался нормальным профилировщиком.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.