Shop OBEX P1 Docs P2 Docs Learn Events
Snippet: Spin2 Code Execution Time — Parallax Forums

Snippet: Spin2 Code Execution Time

I added several new features to my watchdog timer and noticed that my counter stats were off, mostly due to the new code I added. It would normally update stats once a second, but as I added more code and features, that loop got longer and the time based stats were slightly off. I added this code to "firm up" the time the watchdog waits before updating the stats. I thought someone else may find this useful. I am sure it could be improved to take into account it's own overhead, but this is close enough for me.

time1 := GETCT()
Repeat

{

 Do many things in your code. 

}
   ' time2 is the number of microseconds it took for your code to execute.
    time2 := (GETCT() - time1) / (CLKFREQ / 1_000_000)
     ' Wait for 1 second, regardless of variations in time that your code needed within the loop.
    waitus(1_000_000 - time2)
    time1 := GETCT()

Comments

  • You can do better (i.e. avoid precision loss and extraneous divides) by using cycles directly. This will always have a loop time of exactly 1 second. Locks up if you take longer than a second to run the actual thing, but so does your version.

    time1 := GETCT()
    Repeat
    
    {
    
     Do many things in your code. 
    
    }
       ' time2 is the number of **cycles** it took for your code to execute.
        time2 := GETCT() - time1
         ' Wait for 1 second, regardless of variations in time that your code needed within the loop.
        waitct(time1 += (CLKFREQ / 1_000_000))
    
  • JonnyMacJonnyMac Posts: 9,102
    edited 2022-12-31 18:06

    I do timing tests quite frequently -- usually like this

      t := getct()
      { code under test }
      t := getct()-t-40
    

    As this point I have the raw execution time in system ticks. The -40 is based on running under Propeller Tool; this value will be different for FlexProp.

    My programming template includes constants for timing so I would usually display results like this:

      term.fstr1(@"Time = %.3f\r", t/US_001)
    

    ... to display in milliseconds in N.NNN format.

    In my P1 projects I use a file called jm_time_80.spin because we don't have built-in delays. Before Chip restored getms(), I adapted that to the P2 -- that's attached and you may find some bits and bobs interesting. For example, the built-in waitms() and waitus() are limited to delays of about 10 seconds at 200MHz. I have duplicate methods that remove that limitation. This object is also useful for keeping long-running timers. I use a lot of these in the laser-tag project and will be using the P2 version the same way.

    You can declare a timer ojbect and then do something as simple as

      timerx.start(0)
      { code under test }
      elapsed := timerx.millis()
    

    This works over long periods because the delta timing uses the 64-bit system timer.

    I run my projects at 200MHz -- you may need to make a copy of this object with your preferred system frequency. Changing the value of CLK_FREQ is all that's required.

Sign In or Register to comment.