как лучше замерить время выполнения кода
От: SVV Беларусь  
Дата: 27.12.13 13:49
Оценка: -1 :))
Доброго всем времени суток,

пишу класс в котором функционал можно реализовать через функции или операторы (Init/operator= ...)
хочу замерить нет ли потерь производительности при использовании операторов и качество кода Inline функций. Для чего пишу цикл:

STimes1 sT1;
for (u4 u = 0; u < uCycles; ++u)
{
    sMinAW.Init(pszTestStr, 8);
}
u4 uET = sT1.ET();

в дебаг версии для 20 млн циклов время выполнения 1.2 с, а в релиз версии вне зависимости от числа цикло — 0. Понятно что компилятор определил этот цикл как бесполезный, но полностью убрать оптимизацию значит отказаться от оптимизации использованных внутри inline функций. Как сказать компилятору честно выполнить все циклы?
Re: как лучше замерить время выполнения кода
От: мыщъх США http://nezumi-lab.org
Дата: 27.12.13 13:55
Оценка: 1 (1)
Здравствуйте, SVV, Вы писали:

SVV>Доброго всем времени суток,



SVV> Понятно что компилятор определил этот цикл как бесполезный, но полностью убрать оптимизацию

не бесполезный, а вынес инвариант за скобки. чтобы не выносил достаточно функции передавать параметр цикла.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[2]: как лучше замерить время выполнения кода
От: Serg27  
Дата: 27.12.13 14:07
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>Здравствуйте, SVV, Вы писали:


SVV>>Доброго всем времени суток,



SVV>> Понятно что компилятор определил этот цикл как бесполезный, но полностью убрать оптимизацию

М>не бесполезный, а вынес инвариант за скобки. чтобы не выносил достаточно функции передавать параметр цикла.
Кроме того вынести вызываемую функцию в отдельный файл (т.е. в другую единицу трансляции) и отключить глобальную оптимизацию программы. Результат проверить просмотром ассемлиерного листинга.

Ну а вообще то лучше не мерить производительностей отдельных (inline!!!) функций, а измерять производительность всей программы и влияние на нее изменений в коде
Re[3]: как лучше замерить время выполнения кода
От: SVV Беларусь  
Дата: 27.12.13 14:09
Оценка:
Здравствуйте, Serg27, Вы писали:

S>Ну а вообще то лучше не мерить производительностей отдельных (inline!!!) функций, а измерять производительность всей программы и влияние на нее изменений в коде

а если разрабатывается утилитарный класс типа string?
вроде как помогает volatile

volatile u4 uCycles...
Re: как лучше замерить время выполнения кода
От: uzhas Ниоткуда  
Дата: 27.12.13 14:14
Оценка:
Здравствуйте, SVV, Вы писали:

SVV>Как сказать компилятору честно выполнить все циклы?


в режиме телепатии:
1) заюзай переменную sMinAW где-то ниже (после подсчета uET)
2) вставь в цикл инкремент какой-то переменной, а потом ее выведи на экран

зы: предполагаю, что вообще тут нечего оптимизировать, но дело ваше
Re[3]: как лучше замерить время выполнения кода
От: мыщъх США http://nezumi-lab.org
Дата: 27.12.13 14:16
Оценка:
Здравствуйте, Serg27, Вы писали:

S>Здравствуйте, мыщъх, Вы писали:


М>>Здравствуйте, SVV, Вы писали:


SVV>>>Доброго всем времени суток,


S>Кроме того вынести вызываемую функцию в отдельный файл (т.е. в другую единицу трансляции)

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


S> Ну а вообще то лучше не мерить производительностей отдельных (inline!!!) функций,

S> а измерять производительность всей программы и влияние на нее изменений в коде
а еще лучше использовать профилировшик. вызов функции в цикле по любому даст сильно искаженный результат.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[4]: как лучше замерить время выполнения кода
От: uzhas Ниоткуда  
Дата: 27.12.13 14:19
Оценка:
Здравствуйте, мыщъх, Вы писали:

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

кстати, идет подмена понятий : единицей трансляции (translation unit) является один .cpp
первая ссылка из гугла: http://stackoverflow.com/questions/1106149/what-is-a-translation-unit-in-c
Re[5]: как лучше замерить время выполнения кода
От: мыщъх США http://nezumi-lab.org
Дата: 27.12.13 14:27
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, мыщъх, Вы писали:


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

U>кстати, идет подмена понятий : единицей трансляции (translation unit) является один .cpp
несложные тесты показывают, что если функция не инлайн в цикл и если глобальная оптимизация отключена, то можно передавать параметр цикла как аргумент и не использовать -- выноса инварианта не последует. функции транслируются независимо друг от друга. де факто. стандарт об этом ничего не говорит.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[4]: как лучше замерить время выполнения кода
От: Serg27  
Дата: 27.12.13 14:32
Оценка: +1
Здравствуйте, SVV, Вы писали:

SVV>а если разрабатывается утилитарный класс типа string?

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

SVV>вроде как помогает volatile


SVV>
SVV>volatile u4 uCycles...
SVV>


Может быть... Но я могу представить оптимизирующий компилятор, которому доступен весь текст программы, который все равно выкинет ваш вызов из цикла. Еще раз — смотрите ассемблерный листинг.
Re[5]: как лучше замерить время выполнения кода
От: Evgeny.Panasyuk Россия  
Дата: 27.12.13 14:52
Оценка:
Здравствуйте, Serg27, Вы писали:

S>Здравствуйте, SVV, Вы писали:

SVV>>вроде как помогает volatile
SVV>>
SVV>>volatile u4 uCycles...
SVV>>

S>Может быть... Но я могу представить оптимизирующий компилятор, которому доступен весь текст программы, который все равно выкинет ваш вызов из цикла. Еще раз — смотрите ассемблерный листинг.

Всегда использую volatile как барьер для оптимизатора — это работает на MSVC/GCC/Clang, то есть практически везде.
И да — весь код компилятору доступен (один translation unit).
Re: как лучше замерить время выполнения кода
От: VladFein США  
Дата: 27.12.13 14:56
Оценка:
Здравствуйте, SVV, Вы писали:

SVV>Как сказать компилятору честно выполнить все циклы?


Как уже предложил Serg27, не надо измерять время в фиктивных циклах.
Я бы использовал QueryThreadCycleTime.
Re: как лучше замерить время выполнения кода
От: Evgeny.Panasyuk Россия  
Дата: 27.12.13 15:11
Оценка:
Здравствуйте, SVV, Вы писали:

SVV>пишу класс в котором функционал можно реализовать через функции или операторы (Init/operator= ...)

SVV>хочу замерить нет ли потерь производительности при использовании операторов и качество кода Inline функций. Для чего пишу цикл:

В таком случае лучше просто посмотреть на ассемблер, так как часто заинлайненный компилятором код бывает идентичен "заинлайненому" вручную.
Re[2]: как лучше замерить время выполнения кода
От: uzhas Ниоткуда  
Дата: 27.12.13 18:38
Оценка:
Здравствуйте, VladFein, Вы писали:

VF>Как уже предложил Serg27, не надо измерять время в фиктивных циклах.

есть какие-то объективные причины, почему это плохой метод? я бы ознакомился. желательно статьи в инете, которые детально все разжевывают
Re[3]: как лучше замерить время выполнения кода
От: VladFein США  
Дата: 27.12.13 19:35
Оценка:
Здравствуйте, uzhas, Вы писали:

VF>>Как уже предложил Serg27, не надо измерять время в фиктивных циклах.

U>есть какие-то объективные причины, почему это плохой метод? я бы ознакомился. желательно статьи в инете, которые детально все разжевывают

Есть, конечно. У меня нет ссылки на такие статьи, но чем они лучше моего объяснения???
Вы хотите измерить время исполнения Вашего код, всего несколько инструкций. Вместо этого Вы меряете это время плюс накладные расходы но организацию цикла (инкремент и условный переход), которые в Вашем случае могут быть сравнимы со временем исполнения исходного кода.
Кроме этого, в Ваше измеряемое время должно входить время чтения памяти, загрузки регистров и запись обратно в память. В случае цикла эти операции могут исполняться всего один раз, уменьшая их долю в Ваших измерениях в миллионы раз.
В двух словах: Вы измеряете не то, что Вас интересует.
Re[4]: как лучше замерить время выполнения кода
От: uzhas Ниоткуда  
Дата: 27.12.13 20:11
Оценка:
Здравствуйте, VladFein, Вы писали:

VF>Есть, конечно. У меня нет ссылки на такие статьи, но чем они лучше моего объяснения???

спасибо, но в ваших объяснениях ничего полезного не нашел

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

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

в целом, я считаю прогон в цикле хорошей отправной точкой для сравнения сложностей двух алгоритмов и как следствие к оптимизации алгоритмов
Re[5]: как лучше замерить время выполнения кода
От: VladFein США  
Дата: 27.12.13 20:29
Оценка:
Здравствуйте, uzhas, Вы писали:

VF>>Есть, конечно. У меня нет ссылки на такие статьи, но чем они лучше моего объяснения???

U>спасибо, но в ваших объяснениях ничего полезного не нашел

Это обидно...

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

U>это очень суровое предположение,

В оригинале измеряется время исполнения одной строки:
sMinAW.Init(pszTestStr, 8);

Отсюда моё "суровое" предположение. А Ваше — откуда?

U>...к профилировке приходят, когда код выделяется в профайлере. если сложность кода сопоставима с инкрементом и загрузкой переменной в регистр, то я такой код не ускоряю. предположу, что это достаточно редкий случай оптимизировать на таком уровне.

U>обычно ускоряют код, который выделяется в профайлере и занимает значительное время

Профайлер выделяет код, на который уходит много времени. Возможно — за сумасшедшее количество вызовов, при том, что один вызов ничего не стоит... Не знаю, насколько редкий случай; в моей практике встречался.

U>другой момент : если у меня есть две версии алгоритма (пусть даже по сложности сопоставимые с инкрементом переменной), то применив одинаковый метод оценки времени (через прогон в цикле), в обоих случаях я получу одинаковые накладные расходы. это позволит мне сравнить сложность самих алгоритмов.

U>в целом, я считаю прогон в цикле хорошей отправной точкой для сравнения сложностей двух алгоритмов и как следствие к оптимизации алгоритмов

Так а какая, собственно, польза от цикла?
Очевидно, что скорость исполнения второй итерации может быть больше за счёт кэширования. Алгоритм, страдающия от отсутствия кэшированных данных получит несправедливую выгоду при многократном цикле.
Re[6]: как лучше замерить время выполнения кода
От: niXman Ниоткуда https://github.com/niXman
Дата: 27.12.13 20:48
Оценка:
Здравствуйте, VladFein, Вы писали:

VF>Профайлер выделяет код, на который уходит много времени. Возможно — за сумасшедшее количество вызовов, при том, что один вызов ничего не стоит... Не знаю, насколько редкий случай; в моей практике встречался.

о каком профайлере вы говорите? я не встречал профайлера, который умел бы хотя бы инструментировать заинлайненные функции, а вы говорите про ассемблерные инструкции =)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[7]: как лучше замерить время выполнения кода
От: VladFein США  
Дата: 27.12.13 21:07
Оценка:
Здравствуйте, niXman, Вы писали:

VF>>Профайлер выделяет код, на который уходит много времени. Возможно — за сумасшедшее количество вызовов, при том, что один вызов ничего не стоит... Не знаю, насколько редкий случай; в моей практике встречался.

X>о каком профайлере вы говорите? я не встречал профайлера, который умел бы хотя бы инструментировать заинлайненные функции, а вы говорите про ассемблерные инструкции =)

Я говорю о профайлере из MS Visual Studio.
Я *НЕ* говорю об инструментировании ASM или inline; я говорю, что профайлер может указать что функция из трёх строк (вызывающая inline функцию или ASM инструкции) вызывается 100500 раз и занимает 80% времени.
Re: как лучше замерить время выполнения кода
От: VladFein США  
Дата: 02.01.14 20:01
Оценка: :)
Здравствуйте, SVV, Вы писали:

SVV>пишу класс в котором функционал можно реализовать через функции или операторы (Init/operator= ...)

SVV>хочу замерить нет ли потерь производительности при использовании операторов и качество кода Inline функций.

Спор в этой ветке неожиданно ( ) отошёл от Вашего вопроса.
Вот интересная статья про измерение времени:
How to Benchmark Code Execution Times on Intel® IA-32 and IA-64 Instruction Set Architectures
Re: как лучше замерить время выполнения кода
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 03.01.14 07:40
Оценка:
Здравствуйте, SVV, Вы писали:

SVV>в дебаг версии для 20 млн циклов время выполнения 1.2 с, а в релиз версии вне зависимости от числа цикло — 0. Понятно что компилятор определил этот цикл как бесполезный, но полностью убрать оптимизацию значит отказаться от оптимизации использованных внутри inline функций. Как сказать компилятору честно выполнить все циклы?


А если определить sMinAW как volatile?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.