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

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

    Re: spu_clock_read()

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

    Thanks,
    Simon
  • SystemAdmin
    SystemAdmin
    10114 Posts

    Re: spu_clock_read()

    ‏2010-05-21T14:00:14Z  
    My question: how to use the 64-bit counter correctly???

    Thanks,
    Simon
    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

    Re: spu_clock_read()

    ‏2010-05-22T14:16:07Z  
    So here is the output of my application measuring ten times the elapsed time after 10 seconds (sleep).

    <pre class="jive-pre"> 0: 798650126 1: 1596965325 2: 2395285091 3: 3193605714 4: 3991922986 5: 495274988 6: 1293594167 7: 2091913427 8: 2890232686 9: 3688553281 </pre>

    I know that i could reset the clock, but what's then the point of this "64-bit virtual counter" ???
    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

    Re: spu_clock_read()

    ‏2010-05-24T15:46:08Z  
    • andhp
    • ‏2010-05-22T14:16:07Z
    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:

    <pre class="jive-pre"> spu_slih_register(MFC_DECREMENTER_EVENT, spu_clock_slih); </pre>

    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
    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

    Re: spu_clock_read()

    ‏2010-05-24T19:51:19Z  
    Thanks for the answer. I'm still wondering, why this function is designed to support 64-bit values and only returning 32-bit values
    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

    Re: spu_clock_read()

    ‏2010-05-25T13:49:04Z  
    • andhp
    • ‏2010-05-24T19:51:19Z
    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.
    Yes, that's the point! I thought that too, but unfortunately, the function is still not working as supposed.
  • andhp
    andhp
    48 Posts

    Re: spu_clock_read()

    ‏2010-05-26T07:57:58Z  
    Yes, that's the point! I thought that too, but unfortunately, the function is still not working as supposed.
    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

    Re: spu_clock_read()

    ‏2010-05-26T12:11:40Z  
    • andhp
    • ‏2010-05-26T07:57:58Z
    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...
    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

    Re: spu_clock_read()

    ‏2010-05-27T13:26:50Z  
    • kenws
    • ‏2010-05-26T12:11:40Z
    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:

    <pre class="jive-pre"> /* 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; } </pre>

    These are the interesting pieces of the output:
    <pre class="jive-pre"> 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 </pre>

    -ken
    Hmm, thanks for the example, it worked =)