forked from lijiext/lammps
151 lines
4.7 KiB
C++
151 lines
4.7 KiB
C++
/***************************************************************************
|
|
ocl_timer.h
|
|
-------------------
|
|
W. Michael Brown
|
|
|
|
Class for timing OpenCL routines
|
|
|
|
__________________________________________________________________________
|
|
This file is part of the Geryon Unified Coprocessor Library (UCL)
|
|
__________________________________________________________________________
|
|
|
|
begin : Jan Fri 22 2010
|
|
copyright : (C) 2010 by W. Michael Brown
|
|
email : brownw@ornl.gov
|
|
***************************************************************************/
|
|
|
|
/* -----------------------------------------------------------------------
|
|
Copyright (2010) Sandia Corporation. Under the terms of Contract
|
|
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
|
certain rights in this software. This software is distributed under
|
|
the Simplified BSD License.
|
|
----------------------------------------------------------------------- */
|
|
|
|
#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 for timing OpenCL events
|
|
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(); }
|
|
|
|
/// Clear any data associated with timer
|
|
/** \note init() must be called to reuse timer after a clear() **/
|
|
inline void clear() {
|
|
if (_initialized) {
|
|
CL_DESTRUCT_CALL(clReleaseCommandQueue(_cq));
|
|
_initialized=false;
|
|
_total_time=0.0;
|
|
}
|
|
has_measured_time = false;
|
|
}
|
|
|
|
/// Initialize default command queue for timing
|
|
inline void init(UCL_Device &dev) { init(dev,dev.cq()); }
|
|
|
|
/// Initialize command queue for timing
|
|
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;
|
|
}
|
|
|
|
/// Start timing on default command queue
|
|
inline void start() {
|
|
UCL_OCL_MARKER(_cq,&start_event);
|
|
has_measured_time = false;
|
|
}
|
|
|
|
/// Stop timing on default command queue
|
|
inline void stop() {
|
|
UCL_OCL_MARKER(_cq,&stop_event);
|
|
has_measured_time = true;
|
|
}
|
|
|
|
/// Block until the start event has been reached on device
|
|
inline void sync_start() {
|
|
CL_SAFE_CALL(clWaitForEvents(1,&start_event));
|
|
has_measured_time = false;
|
|
}
|
|
|
|
/// Block until the stop event has been reached on device
|
|
inline void sync_stop() {
|
|
CL_SAFE_CALL(clWaitForEvents(1,&stop_event));
|
|
has_measured_time = true;
|
|
}
|
|
|
|
/// Set the time elapsed to zero (not the total_time)
|
|
inline void zero() {
|
|
has_measured_time = false;
|
|
UCL_OCL_MARKER(_cq,&start_event);
|
|
UCL_OCL_MARKER(_cq,&stop_event);
|
|
}
|
|
|
|
/// Set the total time to zero
|
|
inline void zero_total() { _total_time=0.0; }
|
|
|
|
/// Add time from previous start and stop to total
|
|
/** Forces synchronization **/
|
|
inline double add_to_total()
|
|
{ double t=time(); _total_time+=t; return t/1000.0; }
|
|
|
|
/// Add a user specified time to the total (ms)
|
|
inline void add_time_to_total(const double t) { _total_time+=t; }
|
|
|
|
/// Return the time (ms) of last start to stop - Forces synchronization
|
|
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;
|
|
}
|
|
|
|
/// Return the time (s) of last start to stop - Forces synchronization
|
|
inline double seconds() { return time()/1000.0; }
|
|
|
|
/// Return the total time in ms
|
|
inline double total_time() { return _total_time; }
|
|
|
|
/// Return the total time in seconds
|
|
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;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
#endif
|