![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
CPU TimersBoost , ,
|
Таймер домой CPU таймеры Оригинальные таймеры |
Знание того, сколько времени занимает выполнение программы, полезно как в тестовой, так и в производственной среде. Это также может быть полезно, если такая информация о времени разбивается на время настенных часов, время процессора, потраченное пользователем, и время процессора, потраченное операционной системой, обслуживающей запросы пользователей.
Класс<cpu_timer
>измеряет время настенных часов, время обработки процессора пользователя и время обработки процессора системы. Класс<
auto_cpu_timer
>— это уточнение<cpu_timer
>, которое автоматически сообщает о прошедших временах, когда объект<
auto_cpu_timer
>разрушается.
Повышаю. Таймер реализован как отдельно скомпилированная библиотека, поэтому вы должны установить двоичные файлы в месте, которое может быть найдено вашим линкером. Если вы будете следовать инструкциям, чтобы начать, это уже сделано для вас.
auto_cpu_timer
Самое простое и наиболее распространенное использование - добавить две строки, выделенные ниже, в область, которую вы хотите время. См.<
auto_cpu_timer_example.cpp
>Исходный код.
#include <boost/timer/timer.hpp> #include <cmath> int main() { boost::timer::auto_cpu_timer t; for (long i = 0; i < 100000000; ++i) std::sqrt(123.456L); // burn some time return 0; }
Когда<auto_cpu_timer
>объект создан, он начинает отсчет времени. Когда он разрушается в конце области, его деструктор останавливает таймер и отображает информацию о времени на выходном потоке по умолчанию<std::cout
>.
Результат этой программы будет выглядеть примерно так:
< 5.713010s wall, 5.709637s user + 0.000000s system =
5.709637s CPU (99.9%)
>
Другими словами, эта программа работала в<5.713010
>секундах, как измерялось бы часами на стене, операционная система заряжала ее в течение<5.709637
>секунд времени процессора пользователя и 0 секунд времени процессора системы, общее количество этих двух было<5.709637
>, и это составляло<99.9
>процентов времени настенных часов.
Выходной поток, число десятичных знаков и формат отчетности могут контролироваться аргументами конструктора<auto_cpu_timer
>. Вот как будет выглядеть вывод из вышеуказанной программы для нескольких различных наборов аргументов конструктора:
Строительство | Выход |
<t > |
<5.713010s wall, 5.709637s user + 0.000000s system = 5.709637s
CPU (99.9%) > |
<t(std::cerr, 2) > |
<5.71s wall, 5.70s user + 0.00s system = 5.70s CPU (99.9%) > |
<t(1) > |
<5.7s wall, 5.7s user + 0.0s system = 5.7s CPU (99.9%) > |
<t(3, "%w seconds\n") > |
<5.713 seconds > |
<t("%tsec CPU, %w sec real")
> |
<5.709637 sec CPU, 5.713010 sec real > |
Обработка строки формата описаназдесь.
cpu_timer
Следующий код создает контрольную точку каждые 20 CPU секунд:
using boost::timer::cpu_timer; using boost::timer::cpu_times; using boost::timer::nanosecond_type; ... nanosecond_type const twenty_seconds(20 * 1000000000LL); nanosecond_type last(0); cpu_timer timer; while (more_transactions) { process_a_transaction(); cpu_times const elapsed_times(timer.elapsed()); nanosecond_type const elapsed(elapsed_times.system + elapsed_times.user); if (elapsed >= twenty_seconds) { ... create a checkpoint ... last = elapsed; } }
Насколько точны эти таймеры?
The resolution of a clock, and thus timers built on that clock,
is the minimum period time that can be measured. The program
cpu_timer_info.cpp
measures
the resolution of cpu_timer
.
O/S | Processor | Wall-clock | CPU | ||
Resolution | Comments | User Resolution |
System Resolution |
||
Mac OS X Lion | Intel 2007 год | 2100ns 2200ns |
Некоторые вариации в пределах диапазона. | 10000000000 | 10000000000 |
Ubuntu Linux 11.4 | Intel 2005 год | 516ns | Очень мало вариаций, обычно менее 5 нс | 10000000000 | 10000000000 |
Windows 7 | Intel Core i7 860 @ 2,9 ГГц | 366ns | Некоторые вариации, обычно кратные 366n | 15600100000 | 15600100000 |
Windows 7 | Intel Mobile T7200 @ 2.0 ГГц | 2050ns | Много вариаций. Разрешение ухудшается, когда процессор замедляется, вероятно, из-за известных ошибок чипсета. | 15600100000 | 15600100000 |
Windows XP XP | Intel Atom N2800 @ 1,0 ГГц | 1437ns | Некоторые вариации. | 15625000000 | 15625000000 |
Настенные часы подвержены многим внешним воздействиям, таким как влияние других процессов.
<
cpu_timer
>и<auto_cpu_timer
>получают настенные часы от Boost. Хроно<high_resolution_clock
>. На совместимых процессорах Intel, работающих под управлением Windows, Linux и Mac OS X, это «устойчивые часы» [C++11 20.11.3], но они не могут быть устойчивыми на других платформах.<cpu_timer_info.cpp
>сообщает, является ли<high_resolution_clock
>устойчивым на конкретной платформе.Стабильные часыопределяются стандартом C++11 как часы, для которых значения никогда не уменьшаются по мере продвижения физического времени и для которых значения продвигаются с постоянной скоростью относительно реального времени. То есть часы могут не корректироваться. Стабильные часы никогда не работают назад, даже когда часы операционной системы сбрасываются назад, например, во время перехода на летнее время.
Сроки сборки отладки часто в несколько раз медленнее, чем сборки выпуска, потому что оптимизация компилятора отключена и потому что библиотеки часто предоставляют очень дорогие проверки ошибок на сборках отладки.
Синтетический эталонный код может быть оптимизирован, особенно если определен NDEBUG. Возможно, потребуется проверить сгенерированный код, чтобы убедиться, что этого не происходит.
Think about what is important to your application. For a production process, the wall clock time may be what is most important. To study the efficiency of code, total CPU time (user + system) is often a much better measure.
A useful recommendation is to never trust timings unless they are (1) at least 100 times longer than the CPU time resolution, (2) run multiple times, and (3) run on release builds. And results that are too good to be true need to be should be investigated skeptically.
Общие библиотеки (DLL и .so) могут повлечь за собой дополнительные задержки времени, включая дорогостоящие доступы к диску, первый раз, когда таймер или другая функция называется. Если это будет вводить в заблуждение, следует рассмотреть статические ссылки.
Спецификации приведены в стиле стандартной библиотеки C++ (C++11, 17.5.1.4 [structure.specifications]). ДополнительныйОбзорможет быть предоставлен для содействия пониманию.Обзорныеэлементы информативны — фактическая семантика дана другими подробными спецификационными элементами.
Functions not specified as noexcept
will throw
std::bad_alloc
exceptions if a memory allocation error occurs. Other
errors are reported by time values of -1. [Note: Modern hardware and
operating systems have robust clock subsystems, so such errors are unusual if
even possible at all. -- end note]
The Timer library meets the same data race avoidance requirements as the C++11 standard library (17.6.5.9 [res.on.data.races]). Shared objects of Timer library types risk undefined behavior unless the user supplies a locking mechanism. See C++11, 17.6.4.10 [res.on.objects], Shared objects and the library.
<boost/timer/timer.hpp>
synopsis
namespace boost { namespace timer { class cpu_timer; // wall clock, user, and system timer class auto_cpu_timer; // automatic report() on destruction typedef boost::int_least64_t nanosecond_type; struct cpu_times { nanosecond_type wall; nanosecond_type user; nanosecond_type system; void clear(); }; const int default_places = 6; std::string format(const cpu_times& times, short places, const std::string& format); std::string format(const cpu_times& times, short places = default_places); } // namespace timer } // namespace boost |
Формат по умолчанию — "%ws wall, %us user + %ss system = %ts CPU (%p%)\n".
nanosecond_type
Typedef<nanosecond_type
>обеспечивает реализацию определенного типа, способного представлять наносекунды. Для систем POSIX и Windows<
nanoseconds_type
>—<boost::int_least64_t
>.
Основной тип не основан на библиотеке Boost Date-Time или Chrono, чтобы избежать зависимости от большой библиотеки. Этот выбор дизайна может измениться в будущем.
Хотя<nanosecond_type
>способен представлять однунаносекунду, фактическое разрешение общих таймеров операционной системы может быть намного ниже. Для настенных часов примерно в 2010 году разрешение часто не лучше, чем одна 60 микросекунда 61. Для пользовательского и системного времени типичное разрешение составляет 15миллисекундна Windows и 10миллисекундна POSIX.
cpu_times
Структура<cpu_times
>упаковывает прошедшее время настенных часов, время процессора пользовательского процесса и время процессора системного процесса. См.Значения текущего временидля определений источника этих прошедших времен.
void clear();
Эффекты:<
wall = user = system = 0LL
>.
std::string format(const cpu_times& times, short places, const std::string& format); std::string format(const cpu_times& times, short places = default_places);
Обзор:Преобразует значения<
times
>в строки, представляющие секунды до<places
>десятичных знаков, и вставляет их в обратную строку, контролируемую<format
>.Замечания:Для перегрузки без аргумента<
format
>используется форматпо умолчанию.Возвращение:Строка, которая является копией<
format
>, за исключением того, что любые экземпляры последовательностей, показанных ниже, заменяются указанным значением. Времена сообщаются в секундах, показанных в<std::max(0, std::min(default_places, 9))
>десятичных местах. Процент сообщается в одно десятичное место. [править]Примечание:процент может превышать 100% из-за различий в том, как операционные системы измеряют различные времена.— конец примечанияФормат заменяющих последовательностей
Sequence Replacement value %w
< times.wall
>%u
< times.user
>%s
< times.system
>%t
< times.user + times.system
>%p
Доля< times.wall
>, представленная<times.user + times.system
>
cpu_timer
<cpu_timer
>объекты измеряют время, прошедшее через настенные часы, и время, заряженное на пользователя и систему.
Значения текущего времениявляются текущим временем настенных часов, временем пользовательского процесса и временем системного процесса, предусмотренным операционной системой:
cpu_timer
synopsis
class cpu_timer { public: // constructor cpu_timer() noexcept; // compiler generated; shown for exposition only ~cpu_timer() noexcept = default; cpu_timer(const cpu_timer&) noexcept = default; cpu_timer& operator=(const cpu_timer&) noexcept = default; // observers bool is_stopped() const noexcept; cpu_times elapsed() const noexcept; std::string format(int places, const std::string& format) const; std::string format(int places = default_places) const; // actions void start() noexcept; void stop() noexcept; void resume() noexcept; }; |
cpu_timer
constructorcpu_timer() noexcept;
Эффекты:Конструирует объект типа<
cpu_timer
>. Звонки<start()
>.
cpu_timer
observersbool is_stopped() const noexcept;
Возвращение:<
true
>еслиостановится()была самой последнейфункцией действия, названной иначе<false
>.
cpu_times elapsed() const noexcept;
Возвращается:Если<
is_stopped()
>, накопленные прошедшие времена по сравнению с предыдущейостановкой. В противном случае, прошедшее время накапливается между последним вызовомстартаилирезюмеитекущих значений времени.
std::string format(int places, const std::string& format) const; std::string format(int places = default_places) const;
Обзор:Возвращает строку для текущего прошедшего времени в форматес нечленной функцией.
Возвращение:<
boost::timer::format(elapsed(), places[, format])
>.
cpu_timer
actionsvoid start() noexcept;
Effects: Begins accumulating elapsed time as of the current time values.
Постусловия:<
!is_stopped()
>.
void stop() noexcept;
Эффекты:Если<
!is_stopped()
>перестает накапливаться прошедшее время по состоянию натекущие временные значения.[править]Примечание:Это видно по<
elapsed()
>.— конец примечанияПостусловия:<
is_stopped()
>.
void resume() noexcept;
Обзор:Перезапускает таймер, накапливая дополнительное прошедшее время.
Эффекты:Если<
is_stopped()
>, возобновляется накопление дополнительного прошедшего времени, по состоянию натекущие временные значения. В противном случае никакого эффекта.
auto_cpu_timer
Класс<auto_cpu_timer
>добавляет функцию<report()
>к<class cpu_timer
>и автоматически вызывает<report()
>на разрушение.
auto_cpu_timer
synopsis
class auto_cpu_timer : public cpu_timer { public: explicit auto_cpu_timer(short places = default_places); auto_cpu_timer(short places, const std::string& format); explicit auto_cpu_timer(const std::string& format); auto_cpu_timer(std::ostream& os, short places, const std::string& format); explicit auto_cpu_timer(std::ostream& os, short places = default_places); auto_cpu_timer(std::ostream& os, const std::string& format); ~auto_cpu_timer() noexcept; // compiler generated; shown for exposition only auto_cpu_timer(const auto_cpu_timer&) = default; auto_cpu_timer& operator=(const auto_cpu_timer&) = default; // observers std::ostream& ostream() const noexcept; short places() const noexcept; const std::string& format_string() const noexcept; // actions void report(); }; |
[Note: Constructors without a std::ostream&
argument argument imply
std::cout
. An argument default is avoided as it would require including <iostream>
,
with its high costs, even when the standard streams are not used. --end note]
auto_cpu_timer
constructorsexplicit auto_cpu_timer(short places = default_places); auto_cpu_timer(short places, const std::string& format); explicit auto_cpu_timer(const std::string& format); auto_cpu_timer(std::ostream& os, short places, const std::string& format);
explicit auto_cpu_timer(std::ostream& os, short places = default_places);
auto_cpu_timer(std::ostream& os, const std::string& format);
Эффекты:Конструирует объект типа<
auto_cpu_timer
>и хранит поток, места и форматные данные строк, необходимые для установления постусловий.Постусловия:
- Для перегрузок с аргументом
os
,ostream() == os
. В противном случаеostream() == std::cout
.places() == places
.- Для тех, кто перегружен
format
аргументамиformat_string() == format
. В противном случаеformat_string() == std::cout
auto_cpu_timer
destructor~auto_cpu_timer() noexcept;
Effects: If
!is_stopped()
, stop(), report().[Note: Because the function is
noexcept
, implementation must ensure no exception escapes. --end note]
Наблюдатели допускают тестирование пост-условий конструктора и спецификацию других функциональных возможностей, не прибегая к "для экспозиции только" частных участников.
std::ostream& ostream() const noexcept;
Возвращение:Поток хранится путем строительства или последующего копирования.
short places() const noexcept;
Возвращение:Места, хранящиеся при строительстве или последующем копировании.
const std::string& format_string() const noexcept;
Возвращение:Формат строки, сохраненный конструкцией или последующим присвоением копии.
auto_cpu_timer
actionsvoid report();
Эффекты:Как будто:
ostream() << timer::format(elapsed(), places(), format_string());Примечание:Может быть желательно позвонить<
stop()
>, прежде чем позвонить<report()
>, потому что выполнение ввода/вывода во время работы таймера может привести к вводящим в заблуждение результатам.<resume()
>может быть вызван впоследствии для продолжения времени.— конец примечания
Беман Доуз и Роб Стюарт разработали версию 2 библиотеки.
Беман сделал начальную разработку. Роб внес много исправлений, комментариев и предложений. В частности, он предложил функции<resume()
>и<format()
>, что привело к улучшению простоты использования для нескольких вариантов использования.
Комментарии и предложения поступили от Грега Рубино, Дэйва Абрахамса, Висенте Ботета и Джона Мэддока.
Пересмотрено:08 Октябрь 201108 October 2011[ORIG_END] -->
© Copyright Beman Dawes, 2006
© Copyright Beman Dawes and Robert Stewart, 2011
Распространяется в соответствии с Лицензией на программное обеспечение Boost, версия 1.0. См.www.boost.org/ LICENSE_1_0.txt
Статья CPU Timers раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: ::
реклама |