Topic
9 replies Latest Post - ‏2010-05-27T13:26:50Z by SystemAdmin
SystemAdmin
SystemAdmin
10114 Posts
ACCEPTED ANSWER

Pinned topic spu_clock_read()

‏2010-05-21T13:44:07Z |
Hi!

I have a question regarding the function spu_clock_read() from the "SPU Timer Library" spu_timer.h.

According to the document, "SPU Timer Library Programmer’s Guide and API Reference", its a 64-bit counter.


Using the Virtual Clock
The virtual clock provided by the SPU timer library is a 64-bit software managed Time
Base counter that represents the elapsed runtime of the calling thread since the start of the
clock. The clock increments at the Time Base frequency so it can be used to perform
relatively high precision time measurements. The clock is started by calling the
spu_clock_start() service, and is read by calling the spu_clock_read() service.


However, if I use the function spu_clock_read(), it seems to me, that it behaves like a 32-bit counter! I.e., after 2^32 / f seconds, (~54 seconds on the PS3), the counter begins from zero.
Updated on 2010-05-27T13:26:50Z at 2010-05-27T13:26:50Z by SystemAdmin
  • SystemAdmin
    SystemAdmin
    10114 Posts
    ACCEPTED ANSWER

    Re: spu_clock_read()

    ‏2010-05-21T13:46:15Z  in response to SystemAdmin
    My question: how to use the 64-bit counter correctly???

    Thanks,
    Simon
    • SystemAdmin
      SystemAdmin
      10114 Posts
      ACCEPTED ANSWER

      Re: spu_clock_read()

      ‏2010-05-21T14:00:14Z  in response to SystemAdmin
      So here is the output of my application measuring ten times the elapsed time after 10 seconds (sleep).

      
      0: 798650126 1: 1596965325 2: 2395285091 3: 3193605714 4: 3991922986 5: 495274988 6: 1293594167 7: 2091913427 8: 2890232686 9: 3688553281
      


      I know that i could reset the clock, but what's then the point of this "64-bit virtual counter" ???
      • andhp
        andhp
        48 Posts
        ACCEPTED ANSWER

        Re: spu_clock_read()

        ‏2010-05-22T14:16:07Z  in response to SystemAdmin
        I haven't used the library myself, but if I understand correctly, you must register the library-provided second-level interrupt handler spu_clock_slih() for handling decrementer underflows:

        
        spu_slih_register(MFC_DECREMENTER_EVENT, spu_clock_slih);
        


        This must be called before using any of the clock or timer services.
        See http://public.dhe.ibm.com/software/dw/cell/SPU_Runtime_Library_Extensions_v3.1.pdf
        • SystemAdmin
          SystemAdmin
          10114 Posts
          ACCEPTED ANSWER

          Re: spu_clock_read()

          ‏2010-05-24T15:46:08Z  in response to andhp
          Thanks for the answer. I'm still wondering, why this function is designed to support 64-bit values and only returning 32-bit values
          • andhp
            andhp
            48 Posts
            ACCEPTED ANSWER

            Re: spu_clock_read()

            ‏2010-05-24T19:51:19Z  in response to SystemAdmin
            Does it work now, or are you still having the same problem?

            Well, spu_clock_read() should return a monotonically increasing 64-bit value, even though it's based on a 32-bit decrementing counter internally.
            I thought the library's interrupt handler would take care of possible decrementer underflows.
            • SystemAdmin
              SystemAdmin
              10114 Posts
              ACCEPTED ANSWER

              Re: spu_clock_read()

              ‏2010-05-25T13:49:04Z  in response to andhp
              Yes, that's the point! I thought that too, but unfortunately, the function is still not working as supposed.
              • andhp
                andhp
                48 Posts
                ACCEPTED ANSWER

                Re: spu_clock_read()

                ‏2010-05-26T07:57:58Z  in response to SystemAdmin
                Hmm, have you looked into the code in newlib, under newlib/libc/machine/spu?

                Maybe we can figure out how this timer is supposed to work...
                • kenws
                  kenws
                  49 Posts
                  ACCEPTED ANSWER

                  Re: spu_clock_read()

                  ‏2010-05-26T12:11:40Z  in response to andhp
                  Hi,

                  I'm not sure what went wrong on your system. I ran the following testcase using spu-newlib-1.16.0-29 on a QS22:

                  
                  
                  /* spu-gcc -Wall -mstdmain -o timertest timertest.c && ./timertest */ #include <stdio.h> #include <spu_mfcio.h> #include <spu_timer.h>   
                  
                  static unsigned counter;   
                  
                  void myfunc(
                  
                  int id)
                  { ++counter; printf(
                  "myfunc called. id:%d, counter: %03u, overalltime: 0x%016llx\n", id, counter, spu_clock_read()); 
                  }   
                  
                  int main(
                  
                  int argc, 
                  
                  char **argv)
                  { 
                  
                  int timer_id;   
                  /* use library FLIH and SLIH */ spu_slih_register (MFC_DECREMENTER_EVENT, spu_clock_slih);   
                  /* create a new timer */ 
                  /* * The time base is system dependant, see /proc/cpuinfo *   PS3:  79.8   MHz *   QS20: 14.318 MHz *   QS21: 26.67  MHz *   QS22: 26.67  MHz * The spu_timebase() function returns the frequency in Hertz at runtime */ timer_id = spu_timer_alloc(spu_timebase (), myfunc);   
                  /* start clock before timer */ spu_clock_start ();   
                  /* start the timer */ spu_timer_start(timer_id);   
                  
                  while(counter < 600);   
                  /* timer needs to be in a stopped state to be freed */ spu_timer_stop(timer_id); spu_timer_free(timer_id); 
                  /* stop the clock */ spu_clock_stop();   
                  
                  return 0; 
                  }
                  


                  These are the interesting pieces of the output:
                  
                  myfunc called. id:0, counter: 160, overalltime: 0x00000000fe52558f myfunc called. id:0, counter: 161, overalltime: 0x00000000ffe94026 myfunc called. id:0, counter: 162, overalltime: 0x0000000101802914 myfunc called. id:0, counter: 163, overalltime: 0x000000010317155a
                  


                  -ken
                  • SystemAdmin
                    SystemAdmin
                    10114 Posts
                    ACCEPTED ANSWER

                    Re: spu_clock_read()

                    ‏2010-05-27T13:26:50Z  in response to kenws
                    Hmm, thanks for the example, it worked =)