C ++ chrono :: duration_cast всегда выводит 0 секунд

Это мой самый первый вопрос, и я тоже новичок в C ++, но я постараюсь быть максимально конкретным. Скажите, пожалуйста, если я слишком расплывчатый:

Я пытаюсь измерить время, необходимое для метода сортировки (сортировки слиянием) для сортировки заданного массива целых чисел с помощью chrono и duration_cast. Вот фрагмент кода, о котором идет речь:

    auto t1 = std::chrono::high_resolution_clock::now();
    mergesort(sortingArray, temp, 0, num - 1);
    auto t2 = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double, std::milli> fp_ms = t2 - t1;
    std::cout << fp_ms.count() << " seconds\n";

И результат, который я получаю, всегда равен «0 секунд», независимо от того, насколько большим я делаю массив, который нужно отсортировать. Даже когда он сортирует миллион целых чисел и есть заметное время выполнения, он все равно дает мне тот же результат.

Я в основном следую приведенному здесь примеру: http://en.cppreference.com/w/cpp/chrono/duration/duration_cast

Только вместо f () я использую свою функцию mergesort. Как я могу заставить его правильно измерить мой метод сортировки?

РЕДАКТИРОВАТЬ: я использую minGW для компиляции через Powershell в Windows 10. Команда выглядит так:

g++ -std=c++11 .\Merge.cpp

person Jonathan Skogeby    schedule 28.04.2016    source источник
comment
mergesort Ваша собственная функция? Вы уверены, что он действительно сортирует массив?   -  person NathanOliver    schedule 28.04.2016
comment
Да, mergesort это моя собственная функция. Я распечатал отсортированный массив, чтобы убедиться, что он работает.   -  person Jonathan Skogeby    schedule 28.04.2016
comment
Можете ли вы вместо этого попробовать переключить печать наносекунд, чтобы убедиться, что они не округляются до 0. Также подробное описание того, какой компилятор / платформа может помочь вам отследить любые ошибки.   -  person Xornand    schedule 28.04.2016
comment
Хорошо, теперь я переключился на наносекунды, и он дает мне тот же результат, поэтому никакого прогресса в этом нет. Я использую minGW для компиляции через Powershell в Windows 10. Команда выглядит так: g++ -std=c++11 .\Merge.cpp.   -  person Jonathan Skogeby    schedule 28.04.2016
comment
Попробуйте переключиться на steady_clock.   -  person Howard Hinnant    schedule 28.04.2016
comment
К сожалению, никакой разницы нет, Говард :(   -  person Jonathan Skogeby    schedule 28.04.2016
comment
Какая версия MinGW? Возможно, эта функция не реализована.   -  person Lightness Races in Orbit    schedule 28.04.2016


Ответы (1)


TL; DR: похоже, реализация std::chrono (libstdc ++) в Windows довольно плохая, и вы не получите ничего лучше, чем секунды.

Полная версия:

libstdc ++ typedefs std::chrono::high_resolution_clock до std::chrono::system_clock. Согласно реализация вызов std::chrono::system_clock::now() приведет к вызову одного из следующих, в зависимости от платформы:

  • syscall(SYS_clock_gettime, CLOCK_REALTIME, ...) - системный вызов Linux.
  • clock_gettime(CLOCK_REALTIME, ...), который является системным вызовом POSIX, не поддерживаемым Windows.
  • gettimeofday(...), функция POSIX, не поддерживаемая Windows.
  • std::time() в качестве запасного варианта

Таким образом, std::time() вызывается внутри Windows. Кодировка std::time() не указана; однако большинство систем соответствуют спецификации POSIX:

Функция time () должна возвращать значение времени в секундах с начала эпохи.

Сама Microsoft делает то же самое:

Возвращает время как секунды, прошедшее с полуночи 1 января 1970 г., или -1 в случае ошибки.

Я думаю, можно с уверенностью сказать, что вы не получите более высокого разрешения с MingW std::chrono.

Что касается вашей проблемы, у вас есть два варианта:

  1. Если ваша программа работает только в Windows, вы можете создать собственное измерение времени, используя QueryPerformanceCounter
  2. Если вы хотите сохранить портативность, используйте Boost.Chrono . Он использует собственные интерфейсы Windows API и должен предлагать лучшее разрешение.
person Jan Stephan    schedule 28.04.2016
comment
Я выбрал первую альтернативу, и она решила мою проблему. Я использовал следующую реализацию: stackoverflow.com/questions/1739259/ Спасибо! - person Jonathan Skogeby; 28.04.2016
comment
@JonathanSkogeby: Вот как вы можете создать свою собственную хроно-совместимую базу часов на QueryPerformanceCounter stackoverflow.com/a/15755865/576911 Это дает вам всю классную безопасность типов chrono time_points и durations. - person Howard Hinnant; 29.04.2016