stopwatch.h

来自「2002年」· C头文件 代码 · 共 217 行

H
217
字号
#ifndef _STOPWATCH_H
#define _STOPWATCH_H

#ifdef WIN32
#include <winsock2.h>
#define INTEGER64 _int64
#else
#include <sys/time.h>
#define TIME_DIF_TO_MS(s,f) \
    ((f.tv_sec-s.tv_sec)*1000.0 + (f.tv_usec-s.tv_usec)*0.001)
#define INTEGER64 long long
#endif

#include "smp_datastruct.h"

const int Num_Time_Channels = 10;	//the maximum num of channels
const int Num_Time_Events = 1;		//the maximum num of events
const int Num_Cycles = 4;			//the buffer size for a channel
//StopWatch Channels
/*
enum SW_Channel{
SW_CycleStart, //0
SW_Ctrl_UpdateStart, //1
SW_Info_Send_Notify, //2
SW_Ctrl_Recv_Notify, //3
SW_Recv_Visualinfo, //4
SW_Ctrl_Wake, //5
SW_Recv_Fullstateinfo, //6
SW_Ctrl_AIStart, //7
SW_Ctrl_AIExit, //8
SW_Recv_Soundinfo //9
};
*/
const int	SW_CycleStart = 0;
const int	SW_Ctrl_UpdateStart = 1;
const int	SW_Info_Send_Notify = 2;
const int	SW_Ctrl_Recv_Notify = 3;
const int	SW_Recv_Visualinfo = 4;
const int	SW_Ctrl_Wake = 5;
const int	SW_Recv_Fullstateinfo = 6;
const int	SW_Ctrl_AIStart = 7;
const int	SW_Ctrl_AIExit = 8;
const int	SW_Recv_Soundinfo = 9;
/*
enum SW_Event{
SW_Event_ChangeView
};
*/
const int SW_Event_ChangeView = 0;


#ifdef WIN32
typedef LARGE_INTEGER TIME_T;
#else // _LINUX
typedef struct timeval TIME_T;
#endif

union UniformTime{
	struct timeval tv;
	INTEGER64 QuadPart;
};

class Stopwatch{
protected:
	INTEGER64 frequency;				//system info for translating system counts into milisecond.
	
	int current_cycle;				//current cycle
	
	TIME_T inittime;				//time of starting program.
									/* sometimes you can't identify the channel of a time, 
	so cache it before identification */
	TIME_T cachetime;	
	
	/* Channels and Events' time buffer.
	the only difference of event from channel is event is not cycle-based */
	
	typedef TimedDataArray<TIME_T, Num_Cycles> _TDA;
	_TDA Channels[Num_Time_Channels];
	
	TIME_T Events[Num_Time_Events];
	
	/*Millisecond between two times*/
	
	inline float MsBetween(TIME_T& t1, TIME_T& t2){
#ifdef WIN32
		return float(t2.QuadPart - t1.QuadPart)/frequency * 1000.0f;
#else
		return float(TIME_DIF_TO_MS(t1,t2)) / correction_factor;
#endif	
	}

	/* 
	 * correction factor 
	 * Depending on system, there might be systematic multiplicative error in measurement of time.
	 * We estimate that factor and use it to correct our measurement.
	 */
	float correction_factor;
	
public:	
	Stopwatch();
	//set current cycle
	inline void UpdateCycle(int cycle){
		current_cycle = cycle;
	}
	
	//remember current time, you can identify it in the future
	
	inline void Setcachetime(){ 
#ifdef WIN32
		QueryPerformanceCounter(&cachetime);
#else // _LINUX
		gettimeofday(&cachetime, NULL);
#endif
	}
	
	//Identify Cache Time as some channel in some cycle
	inline void IdentifyCachetime(int no, int cycle){
		Channels[no].Setdata(cachetime, cycle);
	}
	//Identify Cache Time as some channel in current cycle
	inline void IdentifyCachetime(int no){
		IdentifyCachetime(no, current_cycle);
	}
	
	//Time some channel of some cycle now
	void TimeNow(int channel, int cycle);
	//Time some channel of current cycle now
	inline void TimeNow(int channel){
		TimeNow(channel, current_cycle);
	}
	
	//Time an event now
	void TimeEvent(int event);
	
	/*The following set of functions are to compute the time gap between two times.
	Most of functions are only for convenient call.
	*/
	//from channel1 of cycle1 to channel2 of cycle2
	inline float MsBetween(int channel1, int cycle1, int channel2, int cycle2){
		return MsBetween(Channels[channel1].Data(cycle1), Channels[channel2].Data(cycle2));
	}
	//from channel1 of current cycle to channel2 of current cycle
	inline float MsBetween(int channel1, int channel2){
		return MsBetween(channel1, current_cycle, channel2, current_cycle);
	}
	//from channel1 of cycle1 to channel1 of cycle2
	inline float MsSpanCycle(int channel, int cycle1, int cycle2){
		return MsBetween(channel, cycle1, channel, cycle2);
	}
	//from channel of cycle-1 to channel of cycle
	inline float MsSpanCycle(int channel, int cycle){
		return MsBetween(channel, cycle-1, channel, cycle);
	}
	/*from channel1 of cycle to channel2 of cycle. 
	return InvalidValue when one or both of them are unknown.*/
	float MsCheckBetween(int channel1, int channel2, int cycle, float InvalidValue = -1.0f);
	/*from channel1 of current cycle to channel2 of current cycle. 
	return InvalidValue when one or both of them are unknown.*/
	inline float MsCheckBetween(int channel1, int channel2, float InvalidValue = -1.0f){
		return MsCheckBetween(channel1, channel2, current_cycle, InvalidValue);
	}
	//from event to channel of cycle
	inline float MsFromEvent(int event, int channel, int cycle){
		return MsBetween(Events[event], Channels[channel].Data(cycle));
	}
	//from event to channel of current cycle
	inline float MsFromEvent(int event, int channel){
		return MsBetween(Events[event], Channels[channel].Data(current_cycle));
	}
	
	//Time elapsed since channel of cycle.
	float TimeElapsed(int channel, int cycle);
	//Time elapsed since channel of current cycle.
	inline float TimeElapsed(int channel){
		return TimeElapsed(channel, current_cycle);
	}
	//Time elapsed since event.
	float TimeElapsed_E(int event);
	
	/*Decide whether event occurs before channel of cycle 
	return true when it does*/
	inline bool IsPrior_E(int event, int channel, int cycle){
		return bool( MsFromEvent(event, channel, cycle) > 0);
	}
	
	/*Extented functions to provide direct access to data*/
	inline TIME_T GetRawData_Channel(int channel, int cycle){
		return Channels[channel].Data(cycle);
	}
	
	TIME_T GetRawData_Event(int event);
	inline TIME_T GetRawData_Cache(){
		return cachetime;
	}
	inline void SetRawData_Channel(TIME_T& t, int no, int cycle){
		Channels[no].Setdata(t, cycle);
	}
	inline void SetRawData_Event(TIME_T& t, int event){
		Events[event] = t;
	}
	inline void SetRawData_Cache(TIME_T& t){
		cachetime = t;
	}
	
	UniformTime FormatTime(TIME_T& t);
	TIME_T DeFormatTime(UniformTime& t);

	void Estimate_correction_factor();
	inline float Get_correction_factor() const{return correction_factor;}
};

namespace World{
	extern Stopwatch stopwatch;
}

#endif //_STOPWATCH_H

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?