Pull to refresh

Оптимизация производительности в C++ приложениях (Windows)

Reading time2 min
Views4.3K
Все думаю уже знают, но все же. Иногда нужно оценить, сколько процессорного времени занимает выполнение тех или иных функций программы(преимущественно я говорю сейчас о C++). Ну и ниже привожу свой способ, простой, но вполне меня устраивает.

Можно проинструментировать код различными специальными инструментами(не пробовал, вроде DevPartner один из них, думаю их немало сейчас).
Функции привязанные к времени не очень то хорошо работают, в WinAPI или в каком либо другом API я их не нашел.

Две функции которые мне весьма пришлись по вкусу:

QueryPerformanceFrequency
QueryPerformanceCounter

Вообще, тут можно заканчивать чтение статьи, чуть погуглить и хватит:)

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

Собственно, QueryPerformanceFrequency возвращает количество элементарных операций которые может выполнить ваш процессор за одну секунду.
QueryPerformanceCounter возвращает количество элементарных операций, которое он уже выполнил с момента запуска компьютера.

«GetTickCount» — вроде как альтернатива, но ее точности мне как то не хватило, либо меня не устроило ее поведение, которое не слишком то внятно описано в MSDN, скорее ее можно использовать только для UI-расчетов.

Вычислить, сколько cекунд занимает вызов какой либо функции (метода класса) DoWork() с использованием QueryPerformanceFrequency/QueryPerformanceCounter собственно весьма просто:

LARGE_INTEGER performanceCounter;
::QueryPerformanceFrequency(&performanceCounter);

LARGE_INTEGER performanceCounterStart;
::QueryPerformanceCounter(&performanceCounterStart);

DoWork();

LARGE_INTEGER performanceCounterEnd;
::QueryPerformanceFrequency(&performanceCounterEnd);

double timeElapsed = (double*)(performanceCounterEnd) - (double*)(performanceCounterEnd)



Грешный код конечно, я лишь показал идею, может вдруг кому и пригодится.
Вообще, QueryPerformanceCounter, это «ReaD Time Stamp Counter(RDTSC)» инструкция ассемблера(вру о5, название инструкции #0f, #31, хотя постесняюсь сказать, на каких процессорах она работает, за что прошу меня простить:)

ЗЫ. При оценке производительности и простейших тестах, коими я иногда пользуюсь, стоит обратить внимание и на компилятор, большинство вменяемых компиляторов блок кода типа

CalculateSinus (cobst Double &x)
{
    return sin(x);
}

static const double x = PI / 4;
double y = CalculateSinus(x)


преобразуют так, что вообще ее не нужно будет считать во время выполнения, и y=sin(PI/4) будет просчитан на стадии компиляии.
Tags:
Hubs:
-2
Comments9

Articles