Получение разницы во времени в наносекундах

Ссылаясь на Получение времени в миллисекундах

Почему приведенный ниже код выводит ноль в качестве вывода?

int main()
{
    steady_clock::time_point t1 = steady_clock::now();
    //std::this_thread::sleep_for(std::chrono::milliseconds(1500));
    steady_clock::time_point t2 = steady_clock::now();
    auto timeC = t1.time_since_epoch().count();
    auto timeD = t2.time_since_epoch().count();
    auto timeA = duration_cast<std::chrono::nanoseconds > ( t1.time_since_epoch()).count();
    auto timeB = duration_cast<std::chrono::nanoseconds > ( t2.time_since_epoch()).count();

    std::cout << timeC << std::endl;
    std::cout << timeB << std::endl;
    std::cout << timeD << std::endl;
    std::cout << timeA << std::endl;

    std::cout << timeB - timeA << std::endl;


    system("Pause");
    return 0;
}

Выход:

14374083030139686
1437408303013968600
14374083030139686
1437408303013968600
0
Press any key to continue . . .

Я предполагаю, что должна быть разница в несколько наносекунд из-за времени выполнения инструкции.


person Gaurav K    schedule 20.07.2015    source источник
comment
Ваши тики не так быстры, как наносекунды, поэтому количество тиков не может быть представлено с точностью до наносекунды. Конечно? Наблюдайте за часами period, чтобы проверить. Вы не можете получить лучшую точность, чем период часов.   -  person Lightness Races in Orbit    schedule 20.07.2015
comment
Даже в миллисекундах он выдает результат как ноль   -  person Gaurav K    schedule 20.07.2015
comment
Что ж, ваш код мало что делает, так что это тоже неудивительно. Что насчет того, если вы добавите сон обратно?   -  person Lightness Races in Orbit    schedule 20.07.2015
comment
@LightnessRacesinOrbit Как вы думаете, может ли компилятор оптимизировать второй вызов функции, поскольку между ними ничего не произошло?   -  person NathanOliver    schedule 20.07.2015
comment
@Nathan - Нет, вызов now(), вероятно, включает вызов ОС, который нельзя оптимизировать. Ваша проблема в том, что вы смотрите на часы чаще, чем двигаются их стрелки.   -  person Bo Persson    schedule 20.07.2015
comment
@BoPersson Спасибо за это.   -  person NathanOliver    schedule 20.07.2015
comment
@NathanOliver: нет, но один вызов для получения времени занимает намного меньше миллисекунды.   -  person Lightness Races in Orbit    schedule 20.07.2015
comment
@BoPersson: хорошая аналогия   -  person Lightness Races in Orbit    schedule 20.07.2015
comment
Назовите свой инструментарий в своем вопросе.   -  person Lightness Races in Orbit    schedule 20.07.2015


Ответы (2)


В VS2012 steady_clock (и high_resolution_clock) использует GetSystemTimeAsFileTime , который имеет очень низкое разрешение ( и не является устойчивым для загрузки). Это признано Microsoft как ошибка.

Обходной путь — использовать VS2015, использовать Boost.Chrono или реализовать собственные часы с помощью QueryPerformanceCounter (см.: https://stackoverflow.com/a/16299576/567292).

person ecatmur    schedule 20.07.2015

То, что вы просите его представить значение в наносекундах, не означает, что точность измерения находится в наносекундах.

Когда вы посмотрите на свой вывод, вы увидите, что счетчик равен наносекундам/100. Это означает, что счетчик представляет время в единицах по 100 наносекунд. Но даже это не говорит вам о периоде базового счетчика, на котором построен steady_clock. Все, что вы знаете, это то, что это не может быть лучше, чем 100 наносекунд.

Вы можете указать фактический период, используемый для счетчика, используя periodчлен steady_clock.

double periodInSeconds = double(steady_clock::period::num) 
                       / double(steady_clock::period::den);

Вернемся к вашему вопросу: «Почему приведенный ниже код выводит ноль в качестве вывода?»

Поскольку между двумя вызовами now() вы не выполнили никакой существенной работы, маловероятно, что вы израсходовали 100 наносекунд, поэтому ответы одинаковы — следовательно, ноль.

person Dale Wilson    schedule 20.07.2015