бенчмаркинг с точностью до миллисекунды в C ++?

Я действительно не хочу профилировать, потому что мне хотелось провести много разных небольших тестов для разных простых функций. За всю жизнь я не могу найти способ записать количество миллисекунд на C ++, кстати, я использую Linux.

Можете ли вы предложить способ получения системных часов в миллисекундах (я могу рассчитаться с секундами, если не могу найти простой способ ..) и в какой заголовок они включены?


person John    schedule 26.09.2010    source источник
comment
Возможный дубликат: stackoverflow.com/questions/307596/time-difference-in-c   -  person Wok    schedule 26.09.2010


Ответы (2)


используя функцию gettimeofday из файла заголовка sys/time.h, я использую этот класс:

#include <cstdlib>
#include <sys/time.h>

class Timer
{
    timeval timer[2];

  public:

    timeval start()
    {
        gettimeofday(&this->timer[0], NULL);
        return this->timer[0];
    }

    timeval stop()
    {
        gettimeofday(&this->timer[1], NULL);
        return this->timer[1];
    }

    int duration() const
    {
        int secs(this->timer[1].tv_sec - this->timer[0].tv_sec);
        int usecs(this->timer[1].tv_usec - this->timer[0].tv_usec);

        if(usecs < 0)
        {
            --secs;
            usecs += 1000000;
        }

        return static_cast<int>(secs * 1000 + usecs / 1000.0 + 0.5);
    }
};

Например:

#include <iostream>
#include <string>
#include <sstream>

int main()
{
    Timer tm;
    std::ostringstream ooo;
    std::string str;

    tm.start();
    for(int i = 0; i < 10000000; ++i)
    {
        ooo << "This is a string. ";
    }
    tm.stop();
    std::cout << "std::ostingstream -> " << tm.duration() << std::endl;

    tm.start();
    for(int i = 0; i < 10000000; ++i)
    {
        str += "This is a string. ";
    }
    tm.stop();
    std::cout << "std::string -> " << tm.duration() << std::endl;
}
person Sadeq    schedule 26.09.2010
comment
wok: Округление, возможно, поможет при преобразовании в int, поэтому 999 округляется до единицы, а не до нуля. - person John; 26.09.2010
comment
@ PC2st: Это был первый раз, когда я полностью понял, что делает код, это мне очень поможет. Раньше я проводил тестирование на PHP, но, черт возьми, неточно измерять алгоритмы. Большое спасибо. - person John; 26.09.2010
comment
@wok: Джон говорит причину, + 0.5 используется для округления результата, но если знак результата был отрицательным, тогда мы должны использовать - 0.5 вместо + 0.5. - person Sadeq; 26.09.2010

Если вы используете процессор x86, вы можете использовать инструкции ассемблера rdtsc http://en.wikipedia.org/wiki/Rdtsc, чтобы получить количество тактов ЦП между выполнением двух (или более) команд. Но: 1. Все команды rdtsc должны выполняться на одном ядре ЦП (в случае, если у вас многоядерный ЦП). 2. ЦП должен работать с постоянной тактовой частотой (управление питанием ЦП должно быть отключено).

Дима

person Dima    schedule 26.09.2010
comment
Интересная мысль, спасибо. извините, я не могу +1, не авторизовался. - person John; 26.09.2010
comment
Некоторые ПК действительно работают по ядрам, другие дрейфуют на сотни миллисекунд. Для программного обеспечения с ошибками при запуске запускайте два связанных с ядром потока, чтобы получить {core1-clocks, core2-clocks, core1-clocks ...}, каждый поток записывает свое значение, как только видит, что другой поток сделал то же самое. На моем ПК дельта между ядрами сузилась до ~ 400 ~ 3 ГГц циклов. Затем, чтобы получить каждую временную метку, CPUID (1) / RDTSC / CPUID (2), вращающийся, если две инструкции CPUID сообщают о разных ядрах. - person user433534; 01.10.2010