[Stackless] stackless profiling?

Jeff Senn senn at maya.com
Thu Aug 29 14:57:21 CEST 2002


"Sam M. Rushing" <srushing at ironport.com> writes:
> Yeah, it's a big problem - the scheduler needs to be profiler-aware.  At
> IronPort we had to hook the resume() interface to charge resources to
...
> real/user/sys, and gives us lots of other info like page swaps,
> interrupts, etc...

Hm.  That sounds interesting.  And probably more accurate than:

The discussion motivated me to patch profile.py a bit (I included the
diff from the version in stackless cvs below).  It only depends on
stackless.getcurrent() (i.e. no mods to my pathetically simple
scheduler) and it runs... sort of... I'm sure the numbers are not real
good.
 
e.g. I suspect part of each time delta is being added to the
destination tasklet state when a switch occurs, when it should be
saved for the source tasklet.  (The only way I see to fix this easily
is to call out to the profiler every time there is a task switch.) 

-- 
-Jas 


--snip--
*** profile.py	Thu Aug 29 08:47:08 2002
--- d:\src\stackless\src\lib\profile.py	Sun Jan 20 19:57:24 2002
***************
*** 4,10 ****
  #
  # Based on prior profile module by Sjoerd Mullender...
  #   which was hacked somewhat by: Guido van Rossum
- #   modified by Jeff Senn (jas) for stackless
  #
  # See profile.doc for more information
  
--- 4,9 ----
***************
*** 40,49 ****
  import os
  import time
  import marshal
- stackless = None
- try:
-   import stackless
- except: pass
  
  __all__ = ["run","help","Profile"]
  
--- 39,44 ----
***************
*** 149,157 ****
      def __init__(self, timer=None, bias=None):
          self.timings = {}
          self.cur = None
-         if stackless != None:
-             self.curs = {}
-             self.tasklet = None
          self.cmd = ""
  
          if bias is None:
--- 144,149 ----
***************
*** 199,218 ****
          self.t = self.get_time()
          self.simulate_call('profiler')
  
-     # if stackless is installed then switch cur based on tasklet
-     def dispatch_enter(self):
-         if stackless == None: return
-         t = hash(stackless.getcurrent())
-         if self.tasklet != t:
-            if self.tasklet != None: #put back prev cur
-                self.curs[self.tasklet] = self.cur
-            self.tasklet = t
-            self.cur = self.curs.get(t)
- 
      # Heavily optimized dispatch routine for os.times() timer
  
      def trace_dispatch(self, frame, event, arg):
-         self.dispatch_enter()
          timer = self.timer
          t = timer()
          t = t[0] + t[1] - self.t - self.bias
--- 191,199 ----
***************
*** 228,234 ****
      # an integer but float works too -- and time.clock() relies on that).
  
      def trace_dispatch_i(self, frame, event, arg):
-         self.dispatch_enter()        
          timer = self.timer
          t = timer() - self.t - self.bias
          if self.dispatch[event](self, frame,t):
--- 209,214 ----
***************
*** 240,246 ****
      # 1/60th second)
  
      def trace_dispatch_mac(self, frame, event, arg):
-         self.dispatch_enter()        
          timer = self.timer
          t = timer()/60.0 - self.t - self.bias
          if self.dispatch[event](self, frame, t):
--- 220,225 ----
***************
*** 251,257 ****
      # SLOW generic dispatch routine for timer returning lists of numbers
  
      def trace_dispatch_l(self, frame, event, arg):
-         self.dispatch_enter()        
          get_time = self.get_time
          t = get_time() - self.t - self.bias
  
--- 230,235 ----
***************
*** 279,288 ****
          if self.cur and frame.f_back is not self.cur[-2]:
              rpt, rit, ret, rfn, rframe, rcur = self.cur
              if not isinstance(rframe, Profile.fake_frame):
!                 # not surprisingly there is some wierdness about stackless.become
!                 # (hence the exception for rframe.f_back == None)
!                 assert rframe.f_back == None or \
!                        rframe.f_back is frame.f_back, ("Bad call", rfn,
                                                         rframe, rframe.f_back,
                                                         frame, frame.f_back)
                  self.trace_dispatch_return(rframe, 0)
--- 257,263 ----
          if self.cur and frame.f_back is not self.cur[-2]:
              rpt, rit, ret, rfn, rframe, rcur = self.cur
              if not isinstance(rframe, Profile.fake_frame):
!                 assert rframe.f_back is frame.f_back, ("Bad call", rfn,
                                                         rframe, rframe.f_back,
                                                         frame, frame.f_back)
                  self.trace_dispatch_return(rframe, 0)
***************
*** 386,399 ****
      def simulate_cmd_complete(self):
          get_time = self.get_time
          t = get_time() - self.t
!         while 1:
!           while self.cur[-1]:
              # We *can* cause assertion errors here if
              # dispatch_trace_return checks for a frame match!
              self.dispatch['return'](self, self.cur[-2], t)
              t = 0
-           if stackless == None or len(self.curs) == 0: break
-           self.cur = self.curs.popitem()[1]
          self.t = get_time() - t
  
  
--- 361,371 ----
      def simulate_cmd_complete(self):
          get_time = self.get_time
          t = get_time() - self.t
!         while self.cur[-1]:
              # We *can* cause assertion errors here if
              # dispatch_trace_return checks for a frame match!
              self.dispatch['return'](self, self.cur[-2], t)
              t = 0
          self.t = get_time() - t
  
  
***************
*** 582,586 ****
      sys.path.insert(0, os.path.dirname(filename))
  
      run('execfile(' + `filename` + ')')
- 
- 
--- 554,556 ----

_______________________________________________
Stackless mailing list
Stackless at www.tismer.com
http://www.tismer.com/mailman/listinfo/stackless



More information about the Stackless mailing list