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() я использую функцию слияния. Как я могу заставить его измерить мой метод сортировки должным образом?

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

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

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. Он использует собственные API-интерфейсы Windows и должен предлагать лучшее разрешение.
Другие вопросы по тегам