Время измерения в многопоточном приложении на С++
Я пишу приложение с использованием С++ и OpenMP, и я хочу надежно (и правильно) измерить время выполнения его частей. Я рассмотрел несколько вариантов (Windows, TDM-GCC x64 4.8.1):
-
omp_get_wproc
и clock
, похоже, выполняют эту работу, но документация (в прямом противоречии с фактическим поведением) говорит, что они измеряют общие временные ресурсы, потребляемые данным процессом (то есть, например, одна секунда с двумя рабочими потоками считается двумя секунд). "Правильное" поведение не то, что я хочу,
-
time
/difftime
не имеют достаточного разрешения,
-
GetProcessTime
(WinAPI) делает то, что часы должны делать и зависит от платформы,
-
QueryPerformanceCounter
(WinAPI), по-видимому, является способом выхода, но является платформенным,
- С++ 11
high_resolution_clock
работает нормально, но это часть нового стандарта.
Мой вопрос, в первую очередь, заключается в следующем: как люди, занимающиеся научными вычислениями, делают это, и почему это так? И, является ли поведение clock
ошибкой в моей реализации стандартной библиотеки или слишком распространенным заблуждением?
EDIT:
Небольшое объяснение: я немного не решаюсь использовать С++ 11, потому что я, вероятно, буду запускать свой код в кластере с несколько старым программным обеспечением.
Ответы
Ответ 1
Вы не упоминали boost::chrono
. То же, что и С++ 11 chrono
, но работает с компилятором С++ 03.
Кроме того, я не могу понять ваши сомнения относительно С++ 11. Мы почти в 2015 году, а С++ 11 не является чем-то новым. Это даже не самый последний стандарт. Итак, #include <chrono>
- это путь.
Обратите внимание, что chrono
несколько нарушается в реализации стандартной библиотеки Visual Studio 2013 Standard. Я лично использую std::chrono
всюду и заменяю его на boost::chrono
через условные defines
и typedef
s. Надеюсь, они исправит его в Visual Studio Next.
Ответ 2
Скопировано прямо из моего текущего исследовательского проекта:
#include <chrono>
#include <type_traits>
/** @brief Best available clock. */
using clock_type = typename std::conditional<
std::chrono::high_resolution_clock::is_steady,
std::chrono::high_resolution_clock,
std::chrono::steady_clock>::type;
Мы хотим измерить время работы настенного времени, а не циклы процессора пользовательского пространства, а также учитывать многопоточные потоки. К сожалению, многие реализации определяют high_resolution_clock
как псевдоним для real_time_clock
, который испортит наши результаты в случае, если время системы будет изменено во время наших измерений.
Да, std::chrono
- это функция С++ 11, но если это исследование, как вы говорите, что мешает вам использовать самый современный компилятор? Вам не понадобится код для компиляции на самой странной платформе, которая может существовать где-то в пыльном подвале клиента. В любом случае, если вы просто не можете иметь С++ 11, вы можете легко реализовать эти часы самостоятельно. Они (по крайней мере, в GNU libstdС++) просто тонкие обертки вокруг clock_gettime
.