Измерение времени в C ++ (gettimeofday) дает повторяющиеся результаты - PullRequest
0 голосов
/ 02 мая 2018

Я пытаюсь вставить несколько элементов в хеш-таблицу и измерить время вставки в миллисекундах. По сути, это работает так (эта функция относится к классу моей хеш-таблицы):

double benchmark(int amountOfInsertions){
    int valueToInsert;
    timeval tv_timeStart, tv_timeEnd;
    double totalTime = 0;
    double db_timeStart, db_timeEnd;

    for (int i = 0; i < amountOfInsertions; i++){

        valueToInsert = generateRandomVariable();

        gettimeofday(&tv_timeStart, NULL);
        insert(valueToInsert);
        gettimeofday(&tv_timeEnd, NULL);

        db_timeStart = tv_timeStart.tv_sec*1000 + tv_timeStart.tv_usec/1000.0;
        db_timeEnd  = tv_timeEnd.tv_sec*1000  + tv_timeEnd.tv_usec/1000.0;

        totalTime += (db_timeEnd - db_timeStart);
    }

    return totalTime;
}

Проблема в том, что время вставки, которое выглядело следующим образом, очевидно, показывает явную прогрессию времени, чем больше элементов я вставил: enter image description here

Но теперь я заметил, что времена вставки чередуются между одними и теми же значениями (кратными 15,625), что приводит к крайне неточным результатам: enter image description here

И это внезапно начало происходить даже со старыми версиями моего кода, которые, как я знаю, выдают правильное время. Это особая проблема с gettimeofday ()? Если нет, то что это может быть?

Эта проблема настолько таинственна для меня, что даже удивляюсь, если это правильное место, чтобы спросить об этом.

ОБНОВЛЕНИЕ: Я также попытался с помощью clock () и std :: chrono :: stable_clock, а также измерил время всего цикла вместо каждой отдельной вставки (пример ниже), и все еще получил то же поведение:

double benchmark(int amountOfInsertions){
    int valueToInsert;
    double totalTime = 0;

    steady_clock::time_point t1 = steady_clock::now();
    for (int i = 0; i < amountOfInsertions; i++){

        valueToInsert = generateRandomVariable();
        insert(valueToInsert);

    }
    steady_clock::time_point t2 = steady_clock::now();

    duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
    totalTime = time_span.count()*1000;

    return totalTime;
}

Ответы [ 2 ]

0 голосов
/ 22 июля 2018

Если вы хотите по-настоящему протестировать это, вам нужно увидеть, какие флаги оптимизации вы используете, что-то оптимизировано, работает ли что-то в фоновом режиме, если контекст переключается с гипертреда, затрагивающего вас и некоторых других. Возможно, использование Celero или Hayai зависит от того, насколько точно вам это нужно. Затем выполните тест по крайней мере 5 раз и поиграйтесь с количеством образцов в тесте.

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

0 голосов
/ 02 мая 2018

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

Пожалуйста, используйте clock_gettime. Или, если вы можете использовать необычные функции C ++ 11: std::chrono::steady_clock

...