Skip to content

Commit 5dbeaa6

Browse files
committed
frame-profiler-debug -> frequent-frame-profiles, limit number of profile loggings in one frame
1 parent 3ce7496 commit 5dbeaa6

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

direct/src/task/FrameProfiler.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
from direct.directnotify.DirectNotifyGlobal import directNotify
22
from direct.fsm.StatePush import FunctionCall
33
from direct.showbase.PythonUtil import formatTimeExact, normalDistrib
4+
from direct.task import Task
45

56
class FrameProfiler:
67
notify = directNotify.newCategory('FrameProfiler')
78

8-
# for precision, all times related to the profile/log schedule are stored as integers
9+
# because of precision requirements, all times related to the profile/log
10+
# schedule are stored as integers
911
Minute = 60
1012
Hour = 60 * Minute
1113
Day = 24 * Hour
@@ -14,7 +16,7 @@ def __init__(self):
1416
Hour = FrameProfiler.Hour
1517
# how long to wait between frame profiles
1618
self._period = 2 * FrameProfiler.Minute
17-
if config.GetBool('frame-profiler-debug', 0):
19+
if config.GetBool('frequent-frame-profiles', 0):
1820
self._period = 1 * FrameProfiler.Minute
1921
# used to prevent profile from being taken exactly every 'period' seconds
2022
self._jitterMagnitude = self._period * .75
@@ -26,7 +28,7 @@ def __init__(self):
2628
12 * FrameProfiler.Hour,
2729
1 * FrameProfiler.Day,
2830
] # day schedule proceeds as 1, 2, 4, 8 days, etc.
29-
if config.GetBool('frame-profiler-debug', 0):
31+
if config.GetBool('frequent-frame-profiles', 0):
3032
self._logSchedule = [ 1 * FrameProfiler.Minute,
3133
4 * FrameProfiler.Minute,
3234
12 * FrameProfiler.Minute,
@@ -113,6 +115,18 @@ def _analyzeResults(self, sessionId):
113115
Functor(self._doAnalysis, sessionId), 'FrameProfilerAnalysis-%s' % sessionId)
114116

115117
def _doAnalysis(self, sessionId, task):
118+
if hasattr(task, '_generator'):
119+
gen = task._generator
120+
else:
121+
gen = self._doAnalysisGen(sessionId)
122+
task._generator = gen
123+
result = gen.next()
124+
if result == Task.done:
125+
del task._generator
126+
return result
127+
128+
def _doAnalysisGen(self, sessionId):
129+
# generator to limit max number of profile loggings per frame
116130
p2ap = self._period2aggregateProfile
117131

118132
self._id2task.pop(sessionId)
@@ -131,14 +145,21 @@ def _doAnalysis(self, sessionId, task):
131145
session.release()
132146
session = None
133147

148+
counter = 0
149+
134150
# log profiles when it's time, and aggregate them upwards into the
135151
# next-longer profile
136152
for pi in xrange(len(self._logSchedule)):
137153
period = self._logSchedule[pi]
138154
if (self._timeElapsed % period) == 0:
139155
if period in p2ap:
156+
# delay until the next frame if we've already processed N profiles this frame
157+
if counter >= 3:
158+
counter = 0
159+
yield Task.cont
140160
self.notify.info('aggregate profile of sampled frames over last %s\n%s' %
141161
(formatTimeExact(period), p2ap[period].getResults()))
162+
counter += 1
142163
# aggregate this profile into the next larger profile
143164
nextIndex = pi + 1
144165
if nextIndex >= len(self._logSchedule):
@@ -161,5 +182,4 @@ def _doAnalysis(self, sessionId, task):
161182
# periods are multiples of this one
162183
break
163184

164-
return task.done
165-
185+
yield Task.done

0 commit comments

Comments
 (0)