#ifndef OCL_TIMER_H
#define OCL_TIMER_H
#include "ocl_macros.h"
#include "ocl_device.h"
#ifdef CL_VERSION_1_2
#define UCL_OCL_MARKER(cq,event) clEnqueueMarkerWithWaitList(cq,0,NULL,event)
#else
#define UCL_OCL_MARKER clEnqueueMarker
#endif
namespace ucl_opencl {
class UCL_Timer {
public:
inline UCL_Timer() : _total_time(0.0f), _initialized(false), has_measured_time(false) { }
inline UCL_Timer(UCL_Device &dev) : _total_time(0.0f), _initialized(false), has_measured_time(false)
{ init(dev); }
inline ~UCL_Timer() { clear(); }
inline void clear() {
if (_initialized) {
CL_DESTRUCT_CALL(clReleaseCommandQueue(_cq));
_initialized=false;
_total_time=0.0;
}
has_measured_time = false;
}
inline void init(UCL_Device &dev) { init(dev,dev.cq()); }
inline void init(UCL_Device &dev, command_queue &cq) {
clear();
t_factor=dev.timer_resolution()/1000000000.0;
_cq=cq;
clRetainCommandQueue(_cq);
_initialized=true;
has_measured_time = false;
}
inline void start() {
UCL_OCL_MARKER(_cq,&start_event);
has_measured_time = false;
}
inline void stop() {
UCL_OCL_MARKER(_cq,&stop_event);
has_measured_time = true;
}
inline void sync_start() {
CL_SAFE_CALL(clWaitForEvents(1,&start_event));
has_measured_time = false;
}
inline void sync_stop() {
CL_SAFE_CALL(clWaitForEvents(1,&stop_event));
has_measured_time = true;
}
inline void zero() {
has_measured_time = false;
UCL_OCL_MARKER(_cq,&start_event);
UCL_OCL_MARKER(_cq,&stop_event);
}
inline void zero_total() { _total_time=0.0; }
inline double add_to_total()
{ double t=time(); _total_time+=t; return t/1000.0; }
inline void add_time_to_total(const double t) { _total_time+=t; }
inline double time() {
if(!has_measured_time) return 0.0;
cl_ulong tstart,tend;
CL_SAFE_CALL(clWaitForEvents(1,&stop_event));
CL_SAFE_CALL(clGetEventProfilingInfo(stop_event,
CL_PROFILING_COMMAND_START,
sizeof(cl_ulong), &tend, NULL));
CL_SAFE_CALL(clGetEventProfilingInfo(start_event,
CL_PROFILING_COMMAND_END,
sizeof(cl_ulong), &tstart, NULL));
clReleaseEvent(start_event);
clReleaseEvent(stop_event);
has_measured_time = false;
return (tend-tstart)*t_factor;
}
inline double seconds() { return time()/1000.0; }
inline double total_time() { return _total_time; }
inline double total_seconds() { return _total_time/1000.0; }
private:
cl_event start_event, stop_event;
cl_command_queue _cq;
double _total_time;
double t_factor;
bool _initialized;
bool has_measured_time;
};
}
#endif