2015-02-03 6 views
1

Я пытаюсь использовать Boost.Chrono для измерения времени процессора моего кода. Мой код C++ для этого приведен ниже. Проблема в том, что иногда я получаю отрицательную длительность. Это происходит, когда я использую «process_real_cpu_clock». Когда я использую «stable_clock», проблема не возникает. Некоторые из выходов я взял следующие:Отрицательная продолжительность с Boost Chrono's process_real_cpu_clock

время для 1-го РЕАЛИЗАЦИЯ: 360 мс

время для 2-го реализации: -3284.97 мс


время для 1-го РЕАЛИЗАЦИЯ: 360 мс

время для 2-й реализации: 1010 мс


время для 1-го РЕАЛИЗАЦИЯ: -3924.97 мс

время для 2-го реализации: 1010 мс

только второй один, как и ожидалось. Я предполагаю, что проблема заключалась в переполнении продолжительности, но в третьем выпуске время для первой реализации должно составлять около 1/3 времени для второго выполнения, тогда не должно быть переполнения, если я смогу увидеть время для второго выполнения. (Я использую подталкивание 1,54, и работать с Ubuntu на VirtualBox)

#include <iostream> 
#include <ctime> 
#include <cstdlib> 
#include <boost/chrono.hpp> 
#include <boost/chrono/process_cpu_clocks.hpp> 

int main() { 

int x,y,result,runs; 
srand(time(NULL)); 
runs=1e7; 


boost::chrono::process_real_cpu_clock::time_point start, start2; 
boost::chrono::process_real_cpu_clock::time_point end, end2; 

start= boost::chrono::process_real_cpu_clock::now(); 

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

     x=rand() %100 +1; 
     y=rand() %100 +1; 
     auto dummy=x*y; 
     result=(result+dummy)%50; 
     } 
end=boost::chrono::process_real_cpu_clock::now(); 
boost::chrono::process_real_cpu_clock::duration diff=end-start; 

start2= boost::chrono::process_real_cpu_clock::now(); 

    for (int i=0;i<(3*runs);i++) { 

     x=rand() %100 +1; 
     y=rand() %100 +1; 
     auto dummy=x*y; 
     result=(result+dummy)%50; 

     } 
end2=boost::chrono::process_real_cpu_clock::now(); 

boost::chrono::process_real_cpu_clock::duration diff2=end2-start2; 

    std::cout << "time for 1st implemention:"<<boost::chrono::duration <double, boost::milli> (diff).count()<< " ns" << std::endl; 
    std::cout << "time for 2nd implementation:"<<boost::chrono::duration <double, boost::milli> (diff2).count()<< " ns" << std::endl; 


return 0; 
} 
+0

Вы уверены, что код является кодом? 'start1' и' end1' здесь не используются. Правильный факторинг кода позволяет избежать таких ситуаций, связанных с ошибкой. Я добавил такое решение, основанное на факторе, на мой ответ (он может быть слишком общим для вашего вкуса). – sehe

+0

Вы правы. 'start1' и' end1' были там из предыдущей версии кода. Я починил это. – oicrisah

ответ

1

Я подозреваю, что вы по ошибке использовали boost::milli (который является только общее отношение назначения от Boost Ratio).

Вы хотите использовать duration_cast с блоками из хроно:

std::cout << "time for 1st implemention:" << duration_cast<nanoseconds>(diff).count() << " ns\n"; 
std::cout << "time for 2nd implementation:" << duration_cast<nanoseconds>(diff2).count() << " ns\n"; 

Вот мой взгляд на него (выбор миллисекунды для удобства чтения):

Live On Coliru

#include <iostream> 
#include <boost/chrono.hpp> 
#include <boost/chrono/process_cpu_clocks.hpp> 

using namespace boost::chrono; 

template <typename R, typename P> 
    static std::ostream& operator<<(std::ostream& os, duration<R,P> const& d) { 
     return os << boost::chrono::duration_cast<boost::chrono::milliseconds>(d).count() << "ms"; 
    } 

template <typename Clock = boost::chrono::process_cpu_clock, typename F, typename... Args> 
nanoseconds bench(F&& f, Args&&... args) { 
    auto start = Clock::now(); 

    volatile auto force = std::forward<F>(f)(std::forward<Args>(args)...); 
    (void) force; 

    return Clock::now() - start; 
} 

long long foo(int runs) { 
    long long result = 0; 
    for (int i = 0; i < runs; i++) { 
     int x = rand() % 100 + 1; 
     int y = rand() % 100 + 1; 
     auto dummy = x * y; 
     result = (result + dummy) % 50; 
    } 

    return result; 
} 

int main() { 
    srand(time(NULL)); 

    std::cout << "1st method: " << bench(foo, 1e7) << "\n"; 
    std::cout << "2nd method: " << bench(foo, 3e7) << "\n"; 
} 

Печать

1st method: 340ms 
2nd method: 1010ms 
+0

Спасибо за ответ @sehe, но выходы, которые я получаю, все еще странные. Некоторые из них, как это: 'первого метода: 503ms второго метод: -1310ms' ' первого метода: -971ms 2-й метода: 1574ms' '1-й метода: 503ms 2-й способ: 99ms' – oicrisah

+0

Я могу только удивляться о ошибке/аномалии реализации под VBox (попробуйте с добавлением/без гостевых дополнений, опциями ускорения/CPU/наборами микросхем?), и вы можете подать билет в Boost Chrono – sehe