2014-10-01 3 views
1

Я пишу приложение с использованием C++ и OpenMP, и я хочу надежно (и правильно) измерить время выполнения его частей. Я рассмотрел несколько вариантов (Windows, TDM-GCC x64 4.8.1):Время измерения в многопоточном приложении C++

  1. omp_get_wproc и clock, кажется, чтобы сделать работу, но документацию (в прямом противоречии с реальным поведением) говорит, что они измеряют общее время ресурсы, потребляемые по данному процессу (то есть, например, одна секунда с двумя рабочими потоками считается равной двум секундам). «Правильное» поведение не то, что я хочу,
  2. time/difftime не имеют достаточного разрешения,
  3. GetProcessTime (WinAPI) делает то, что часы должны делать и от платформы,
  4. QueryPerformanceCounter (WinAPI), похоже, путь, но является платформенным,
  5. C++ 11 high_resolution_clock работает нормально, но это часть нового стандарта.

Мой вопрос, в первую очередь, заключается в следующем: как люди, занимающиеся научными вычислениями, делают это, и почему это так? И, является ли поведение clock ошибкой в ​​моей реализации стандартной библиотеки или слишком распространенным заблуждением?

EDIT: Небольшое объяснение: я немного нерешительно использую C++ 11, потому что я, вероятно, буду запускать свой код в кластере с несколько старым программным обеспечением.

+0

W.r.t Новый стандарт и 'high_resolution_clock' - это код, необходимый для совместимости с C++ 03? – Niall

+0

Вы также можете взглянуть на boost :: chrono, он предоставляет несколько удобную оболочку для того, что бы ни случилось в настоящее время. – ecotax

+0

Право, я действительно посмотрел на boost :: chrono, чтобы найти, что для Windows он фактически использует QueryPerformanceCounter – matb

ответ

1

Вы не указали boost::chrono. То же, что и C++ 11 chrono, но работает с компилятором C++ 03.

Кроме того, я не могу понять ваши сомнения относительно C++ 11. Мы почти в 2015 году, а C++ 11 не является чем-то новым. Это даже не самый последний стандарт. Итак, #include <chrono> - это путь.

Обратите внимание, что chrono несколько нарушен в реализации стандартной библиотеки Visual Studio 2013 Standard. Я лично использую std::chrono всюду и свопим его на boost::chrono через условное defines и typedef s. Надеюсь, они исправит его в Visual Studio Next.

+0

О да, Boost, вероятно, даже лучший выбор, чем сама система. По крайней мере, если Boost уже является зависимостью вашего проекта. – 5gon12eder

+0

@ 5gon12eder Достаточно честный. Еще хуже. На самом деле, чтобы использовать boost, вам понадобятся две скомпилированные библиотеки: 'boost_chrono' и' boost_system'. Хотя, если мы говорим о кросс-платформенном потоке с C++ 03, мы, вероятно, уже имеем 'boost :: thread' и' boost :: system' в качестве зависимостей, поэтому 'boost :: chrono' отлично подходит здесь , – Drop

3

переписываются прямо с моего текущего исследовательского проекта:

#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 - это функция C++ 11, но если это исследование, как вы говорите, что мешает вам использовать самый современный компилятор? Вам не понадобится код для компиляции на самой странной платформе, которая может существовать где-то в пыльном подвале клиента. В любом случае, если вы просто не можете иметь C++ 11, вы можете легко реализовать эти часы самостоятельно. Они (по крайней мере, в GNU libstdC++) просто тонкие обертки вокруг clock_gettime.

+0

На этом переключателе типов: Обычно 'high_resolution_clock' является typedef для' system_clock' или 'stable_clock'. Таким образом, чтобы проследить этот 'std :: условный', если часть' is_steady' верна, вы выбираете 'high_resolution_clock', который (typedef) для' stable_clock'. Если это ложь, вы снова выбираете 'stable_clock'. Просто используйте 'stable_clock' с самого начала ... –

+1

@NikosAthanasiou Хотя это может быть« типично », стандарт не дает этого. 'std :: chrono :: {system, stable, high_resolution} _clock' * может * быть реализован как три разных такта. Это не означает, что 'stable_clock' не является достойным выбором на практике. – 5gon12eder

+0

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

Смежные вопросы