Неверное измерение std::chrono после обновления до gcc 4.9.2

Я использую следующее для определения времени своих модульных тестов:

template<typename F>
void TestFunc(F lambda)
{
    std::array<std::chrono::milliseconds::rep, 20> time;

    for (int i = 0; i < 10; ++i) {
        auto t1 = std::chrono::high_resolution_clock::now();

        for (int j = 0; j < 1000; ++j) {
            lambda();
        }

        auto t2 = std::chrono::high_resolution_clock::now();

        time[i] = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
    }

    size_t avg = std::accumulate(begin(time), end(time), (std::chrono::milliseconds::rep)0) / time.size();

   ...
}

Но я получаю поврежденные результаты на ubuntu + gcc 4.9.2. Такие значения, как 21006482932417, где gcc 4.8 и VS2013 возвращают 4 мс

До обновления gcc с 4.8.x до 4.9.2 измерения были правильными. Может быть, использовалась неправильная версия libstd? Я запустил ldd, чтобы проверить

> ldd ./bin/unittest
    linux-vdso.so.1 =>  (0x00007fff039fe000)
    libboost_chrono.so.1.57.0 => /usr/local/lib/libboost_chrono.so.1.57.0 (0x00007fde053c2000)
    libboost_system.so.1.57.0 => /usr/local/lib/libboost_system.so.1.57.0 (0x00007fde051bd000)
    libboost_filesystem.so.1.57.0 => /usr/local/lib/libboost_filesystem.so.1.57.0 (0x00007fde04fa6000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fde04d7c000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fde04a6f000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fde04858000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fde04492000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fde04289000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fde057f7000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fde03f83000)

Также пытался переключиться на boost::chrono, но это тоже не помогло. Что может быть возможной причиной?


person kittikun    schedule 17.11.2014    source источник
comment
Похоже, вы выделяете место 20 раз, а затем заполняете первые 10. Последние 10, вероятно, не равны 0.   -  person Retired Ninja    schedule 17.11.2014
comment
@RetiredNinja Действительно, пожалуйста, опубликуйте это как ответ, и я отмечу его как правильный. Большое спасибо!   -  person kittikun    schedule 17.11.2014


Ответы (1)


Вы выделяете массив из 20 элементов, но присваиваете значения только первым 10, поэтому остальные унифицируются. Даже если бы они были инициализированы до 0, они бы отбрасывали средний расчет. Вы можете сделать что-то вроде этого, когда вы передаете количество раз для запуска теста, чтобы размеры не рассинхронизировались.

#include <algorithm>
#include <array>
#include <chrono>
#include <functional>
#include <iostream>
#include <numeric>
#include <vector>

template <size_t N, typename F>
void TestFunc(F lambda)
{
    std::array<std::chrono::milliseconds::rep, N> time;

    for(int i = 0; i < N; ++i)
    {
        auto t1 = std::chrono::high_resolution_clock::now();
        for(int j = 0; j < 1000; ++j)
        {
            lambda();
        }
        auto t2 = std::chrono::high_resolution_clock::now();
        time[i] = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
    }
    auto avg = std::accumulate(begin(time), end(time), (std::chrono::milliseconds::rep)0) / time.size();
    std::cout << "Average of " << N << " tests is " << avg << "ms.\n";
}

int main()
{
    std::function<int()> f = []()
    {
        int sum = 0; for(int i = 0; i < 100000; ++i) sum += i; return sum;
    };
    TestFunc<10>(f);
    return 0;
}

У меня нет под рукой gcc 4.9.2 для тестирования, но он хорошо работал в Visual Studio 2013 и на ideone. .

person Retired Ninja    schedule 17.11.2014