[Top] [All Lists]

Re: Cycle counter

To: "Gareth" <>, <>
Subject: Re: Cycle counter
From: "Kevin D. Kissell" <>
Date: Fri, 13 Sep 2002 19:10:28 +0200
Original-recipient: rfc822;
References: <>
A few comments, a couple of which are in common with
Nick's response.

1) With anything except the absolutely latest MIPS CPU
     design (the M4K), you cannot access the Count register
     unless you have full system coprocessor access, which
     is to say, unless you are in the kernel.  If you're doing
     this in user mode, I would expect you to get a SIGILL
     on your mtc0/mfc0.  If you're embedding your code
     in the kernel and triggering it via a system call, and if
     you disable interrupts during the sample interval, you
     should get a more-or-less accurate result.

2)  As Nick points out, you should absolutely never
     *write* to the count register.  Sample it and compute
     deltas, but do not change it, as system timing depends
     on it in many (most?) kernels.

3)  Make sure you check the users manual for your CPU
      to determine whether the count register is incremented
      every cycle or every two cycles.

4)  Personally, when I want to know how long a loop takes
     to execute under Linux, I generally use the good old-fashioned
     gettomeofday() system call to time a very large number of
     iterations of the loop, enough to run for 10 seconds or
     so, and divide by the number of iterations.  That won't
     give you the worst-case, caches-cold execution time,
     but it will give you a very close approximation of the
     Nth iteration time, without having to embed the code
     in the kernel.


            Kevin K.
----- Original Message ----- 
From: "Gareth" <>
To: <>
Sent: Friday, September 13, 2002 6:28 PM
Subject: Cycle counter

> Hi,
> Another question reagarding the mips malta board. I am wanting to be able to
> find out how many cycles a certain loop takes to execute. I understand there 
> is
> a cycle counter built into the processor that I want to use for this. I have a
> bit of inline assembly to do the job but the results I am getting are not
> consistent so i think there is probably something wrong with my attempt at the
> inline assembly. Here is the code : 
>   void al_signal_start(void);
>   size_t al_signal_finished(void);
>   unsigned int GetcpuCycles(void);
>   char str[8];
>   int main (void)
>   {
>       double x;
>       al_signal_start();
>       x = al_signal_finished();
>       printf("GetcpuCycles says : %f \n",x);
>       return 0;
>   }
>   size_t al_signal_finished(void)
>   {
>       return GetcpuCycles(); 
>   }
>   void al_signal_start(void)
>   {
>   int zero,temp;
>   __asm__("move $2, $zero");
>   __asm__("nop");
>           __asm__("mtc0 $2, $9" :  : "r" (temp));
>           __asm__("nop");
>           __asm__("nop");
>           __asm__("nop");
>   }
>   unsigned int GetcpuCycles(void)
>   {
>           int temp;
>           __asm__(".set reorder");
>           __asm__("mfc0 $2, $9" : : "r" (temp));
>           __asm__("nop");
>           __asm__("nop");
>           __asm__("nop");
>           /*__asm__("jr $31" );*/
>   }
> As you can see, main just starts and stops the counter with no instructions in
> between. I expexcted the cycle count to be zero or close to it because of the
> instructions required to get the count but this is not the case. I am getting
> numbers like 8499. Is there just something wrong with my assembly or is there
> something else I am missing?
> Thanks for any help
> Gareth

<Prev in Thread] Current Thread [Next in Thread>