Время измерения в многопоточном приложении на С++

Я пишу приложение с использованием С++ и 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.