panthema / 2013 / parallel-string-sorting / parallel-string-sorting-0.6.5 / src / tools / timer.h (Download File)
/******************************************************************************
 * src/tools/timer.h
 *
 * Class to output statistics in a flexible text file as key=value pairs.
 *
 ******************************************************************************
 * Copyright (C) 2012-2013 Timo Bingmann <tb@panthema.net>
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 *****************************************************************************/

#ifndef TOOLS_TIMER_H
#define TOOLS_TIMER_H

#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <unistd.h>

#include <assert.h>
#include <omp.h>

//! very simple class to measure runtime of function using clock_gettime.
template <clockid_t clk_id>
class ClockTimerBase
{
protected:
    //! time of start
    struct timespec     m_tstart;

    //! call gettime
    static inline void get_time(struct timespec& ts)
    {
        if (clock_gettime(clk_id, &ts)) {
            perror("Could not clock_gettime()");
        }
    }

public:
    //! Initialize and (usually) start clock
    ClockTimerBase(bool do_start = true)
    {
        if (do_start) start();
    }

    //! return the resolution of the clock used
    static inline double resolution()
    {
        struct timespec tp_res;

        if (clock_getres(clk_id, &tp_res)) {
            perror("Could not clock_getres()");
            return -1;
        }

        return tp_res.tv_sec + tp_res.tv_nsec / 1e9;
    }

    //! Start timing
    inline void start()
    {
        get_time(m_tstart);
    }

    //! Return time elapsed in seconds between start() and now.
    inline double elapsed() const
    {
        struct timespec now;
        get_time(now);

        return (now.tv_sec - m_tstart.tv_sec)
            +  (now.tv_nsec - m_tstart.tv_nsec) / 1e9;
    }
};

//! Most simple ClockTimer instance for easy measurements
typedef ClockTimerBase<CLOCK_MONOTONIC> ClockTimer;

//! Extended class to measure runtime of function using clock_gettime, with
//! start() - stop() semantics.
template <clockid_t clk_id>
class ClockIntervalBase : public ClockTimerBase<clk_id>
{
protected:
    //! type of super class
    typedef ClockTimerBase<clk_id> super_type;

    //! time of stop
    struct timespec     m_tstop;

public:
    //! Initialize, but do not start the clock
    ClockIntervalBase()
        : super_type(false)
    {
    }

    //! Stop timing
    inline void stop()
    {
        super_type::get_time(m_tstop);
    }

    //! Return delta in seconds between start() and stop().
    inline double delta() const
    {
        return (m_tstop.tv_sec - super_type::m_tstart.tv_sec)
            +  (m_tstop.tv_nsec - super_type::m_tstart.tv_nsec) / 1e9;
    }

    //! Retrun delta in seconds between start() and now.
    inline double delta_now() const
    {
        return super_type::delta();
    }
};

#endif // TOOLS_TIMER_H