98 subroutine start_timer(this, name)
100 character(len=*),
intent(in) :: name
103 timer_idx = this % insert_time(name)
105 if (this % timers(timer_idx) % active)
then
106 write (stdout,
"('TimerStart: timer ',a,' is already active')") trim(name)
107 stop
'TimerStart - nested timer'
111 this % timer_active = this % timer_active + 1
112 this % nested_timers(this % timer_active) = timer_idx
114 this % timers(timer_idx) % active = .true.
115 this % timers(timer_idx) % stack_p = this % timer_active
116 this % timers(timer_idx) % calls = this % timers(timer_idx) % calls + 1
117 this % timers(timer_idx) % real_start = get_real_time()
127 subroutine stop_timer (this, name)
129 character(len=*),
intent(in) :: name
131 real(wp) :: real_time
132 type(time_data),
pointer :: pt_timer
134 timer_idx = this % insert_time(name)
135 real_time = get_real_time() - this % timers(timer_idx) % real_start
137 this % timers(timer_idx) % real_time = this % timers(timer_idx) % real_time + real_time
138 this % timers(timer_idx) % active = .false.
140 this % timer_active = this % timer_active - 1
142 if (this % timer_active > 0)
then
143 this % timers(this % nested_timers(this % timer_active)) % real_kids &
144 = this % timers(this % nested_timers(this % timer_active)) % real_kids + real_time
154 integer function insert_time (this, name)
156 character(len=*),
intent(in) :: name
158 insert_time = string_hash(name, timer_default_size)
161 if (.not. this % timers(insert_time) % used)
then
163 this % timer_count = this % timer_count + 1
164 if (this % timer_count >= timer_default_size / 5)
then
165 write (stdout,
"('Too many timers. Increase table_size in timer.f90 to at least ',i5)") this % timer_count * 5
166 stop
'timer%insert_item'
168 this % order(this % timer_count) = insert_time
169 this % timers(insert_time) % used = .true.
170 this % timers(insert_time) % active = .false.
171 this % timers(insert_time) % name = name
172 this % timers(insert_time) % calls = 0
173 this % timers(insert_time) % real_time = 0
175 this % timers(insert_time) % real_kids = 0
180 if (this % timers(insert_time) % name == name)
then
185 insert_time = 1 + modulo(insert_time - 2, timer_default_size)
195 subroutine report_timers (this)
197 real(wp) :: real_now, real_time, cpu_time, real_kids, cpu_kids, real_threshold
199 integer :: ord, pos, kid_pos, omitted
201 type(time_data),
pointer :: t, k
202 character(len=1) :: active
204 real_now = get_real_time()
205 real_threshold = 0.01_wp * (real_now - this % program_start)
207 write (stdout,
"(t2,' ',t38,' ',t45,'Total time (seconds)',t67,'Self time (seconds)')")
208 write (stdout,
"(t2,'Timer',t38,'Calls',t45,'--------------------',t67,'-------------------')")
209 write (stdout,
"(t2,'-----',t38,'-----',t50,'Real',t61,'CPU',t72,'Real',t83,'CPU')")
214 scan:
do ord = 1, this % timer_count
216 pos = this % order(ord)
217 if (.not. this % timers(pos) % used)
then
218 write (stdout,
"('Timer ',i4,' in slot ',i5,' is defined but unused?!')") ord, pos
219 stop
'TimerReport - logic error'
223 real_time = 0 ; real_kids = 0 ;
224 cpu_time = 0 ; cpu_kids = 0 ;
226 if (this % timers(pos) % active)
then
227 real_time = real_now - this % timers(pos) % real_start
229 if (this % timer_active /= this % timers(pos) % stack_p)
then
232 kid_pos = this % nested_timers(this % timers(pos) % stack_p + 1)
233 real_kids = real_now - this % timers(kid_pos) % real_start
239 real_time = real_time + this % timers(pos) % real_time
241 real_kids = real_kids + this % timers(pos) % real_kids
245 if (real_time < real_threshold)
then
246 omitted = omitted + 1
251 write (stdout,
"(t2,a30,t33,a1,t35,I8,t45,2(f9.1,1x,f9.1,3x))") &
252 this % timers(pos) % name, active, this % timers(pos) % calls, real_time, cpu_time, &
253 real_time - real_kids, cpu_time - cpu_kids
257 if (omitted > 0)
then
258 write (stdout,
"(/' (',i3,' timers contributing less than 1% are not shown)')") omitted