* Cycle counter
@ 2002-09-13 16:28 Gareth
2002-09-13 17:10 ` Kevin D. Kissell
[not found] ` <Pine.BSF.4.10.10209130937060.47912-100000@mail.matriplex.com>
0 siblings, 2 replies; 7+ messages in thread
From: Gareth @ 2002-09-13 16:28 UTC (permalink / raw)
To: linux-mips
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
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: Cycle counter
2002-09-13 16:28 Cycle counter Gareth
@ 2002-09-13 17:10 ` Kevin D. Kissell
2002-09-13 17:10 ` Kevin D. Kissell
[not found] ` <Pine.BSF.4.10.10209130937060.47912-100000@mail.matriplex.com>
1 sibling, 1 reply; 7+ messages in thread
From: Kevin D. Kissell @ 2002-09-13 17:10 UTC (permalink / raw)
To: Gareth, linux-mips
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.
Regards,
Kevin K.
----- Original Message -----
From: "Gareth" <g.c.bransby-99@student.lboro.ac.uk>
To: <linux-mips@linux-mips.org>
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
>
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: Cycle counter
2002-09-13 17:10 ` Kevin D. Kissell
@ 2002-09-13 17:10 ` Kevin D. Kissell
0 siblings, 0 replies; 7+ messages in thread
From: Kevin D. Kissell @ 2002-09-13 17:10 UTC (permalink / raw)
To: Gareth, linux-mips
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.
Regards,
Kevin K.
----- Original Message -----
From: "Gareth" <g.c.bransby-99@student.lboro.ac.uk>
To: <linux-mips@linux-mips.org>
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
>
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
[parent not found: <Pine.BSF.4.10.10209130937060.47912-100000@mail.matriplex.com>]
* Re: Cycle counter
[not found] ` <Pine.BSF.4.10.10209130937060.47912-100000@mail.matriplex.com>
@ 2002-09-16 9:02 ` Gareth
0 siblings, 0 replies; 7+ messages in thread
From: Gareth @ 2002-09-16 9:02 UTC (permalink / raw)
To: Richard Hodges; +Cc: linux-mips
Thanks for the help. This program is not running in linux, it is running as a
single application on the core. The processor is a 4kc. I tried your code and it
works fine. I just deleted your do_something() so the timer starts and stops
immediatly. I get 21 ticks now rather than the 8000 or so I was getting with my
code which is much more realistic.
On Fri, 13 Sep 2002 09:41:27 -0700 (PDT)
Richard Hodges <rh@matriplex.com> wrote:
> On Fri, 13 Sep 2002, Gareth wrote:
>
> > 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)
> > {
> > int zero,temp;
> > __asm__("move $2, $zero");
> > __asm__("nop");
> > __asm__("mtc0 $2, $9" : : "r" (temp));
>
> Is this from user space? If so, this may fail from user space. (I sure
> hope it does!)
>
> > 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?
>
> Try something like this:
>
> #define GET_CLOCK(var){__asm__ volatile("mfc0 %0,$9":"=r"(var));}
> {
> unsigned int clock1, clock2;
>
> GET_CLOCK(clock1);
> do_something();
> GET_CLOCK(clock2);
>
> printf("ticks = %d\n", clock2 - clock1);
> }
>
> -Richard
>
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: Cycle counter
@ 2002-09-13 16:40 Zajerko-McKee, Nick
2002-09-13 16:51 ` Matthew Dharm
0 siblings, 1 reply; 7+ messages in thread
From: Zajerko-McKee, Nick @ 2002-09-13 16:40 UTC (permalink / raw)
To: 'Gareth', linux-mips
Is this under a OS or a single execution? Are there interrupts enabled? If
so, disable them for measurements. (Clock interrupt, serial port, etc.).
BTW, most MIPS implementations for OS's and monitors use the count/compare
for their main tick. If you set it to zero you may be stepping on someone's
tick. A better method might be to read the count register and read it again
at the end and do a difference - that way you preserve other's values.
Other reasons for a delay: to fetch code (external mem ->cache -> cpu) and
push items onto/off the stack... Theres probably more that I can't think of
right now...
-----Original Message-----
From: Gareth [mailto:g.c.bransby-99@student.lboro.ac.uk]
Sent: Friday, September 13, 2002 12:28 PM
To: linux-mips@linux-mips.org
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
^ permalink raw reply [flat|nested] 7+ messages in thread* RE: Cycle counter
2002-09-13 16:40 Zajerko-McKee, Nick
@ 2002-09-13 16:51 ` Matthew Dharm
2002-09-13 16:51 ` Matthew Dharm
0 siblings, 1 reply; 7+ messages in thread
From: Matthew Dharm @ 2002-09-13 16:51 UTC (permalink / raw)
To: Zajerko-McKee, Nick, 'Gareth', linux-mips
Does this even run in userspace? When I try something like this
(using mfc0) in userspace, I get an illegal instruction exception.
Matt
--
Matthew D. Dharm Senior Software Designer
Momentum Computer Inc. 1815 Aston Ave. Suite 107
(760) 431-8663 X-115 Carlsbad, CA 92008-7310
Momentum Works For You www.momenco.com
> -----Original Message-----
> From: linux-mips-bounce@linux-mips.org
> [mailto:linux-mips-bounce@linux-mips.org]On Behalf Of Zajerko-McKee,
> Nick
> Sent: Friday, September 13, 2002 9:41 AM
> To: 'Gareth'; linux-mips@linux-mips.org
> Subject: RE: Cycle counter
>
>
> Is this under a OS or a single execution? Are there
> interrupts enabled? If
> so, disable them for measurements. (Clock interrupt, serial
> port, etc.).
>
> BTW, most MIPS implementations for OS's and monitors use
> the count/compare
> for their main tick. If you set it to zero you may be
> stepping on someone's
> tick. A better method might be to read the count register
> and read it again
> at the end and do a difference - that way you preserve
> other's values.
>
> Other reasons for a delay: to fetch code (external mem
> ->cache -> cpu) and
> push items onto/off the stack... Theres probably more that
> I can't think of
> right now...
>
> -----Original Message-----
> From: Gareth [mailto:g.c.bransby-99@student.lboro.ac.uk]
> Sent: Friday, September 13, 2002 12:28 PM
> To: linux-mips@linux-mips.org
> 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
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread* RE: Cycle counter
2002-09-13 16:51 ` Matthew Dharm
@ 2002-09-13 16:51 ` Matthew Dharm
0 siblings, 0 replies; 7+ messages in thread
From: Matthew Dharm @ 2002-09-13 16:51 UTC (permalink / raw)
To: Zajerko-McKee, Nick, 'Gareth', linux-mips
Does this even run in userspace? When I try something like this
(using mfc0) in userspace, I get an illegal instruction exception.
Matt
--
Matthew D. Dharm Senior Software Designer
Momentum Computer Inc. 1815 Aston Ave. Suite 107
(760) 431-8663 X-115 Carlsbad, CA 92008-7310
Momentum Works For You www.momenco.com
> -----Original Message-----
> From: linux-mips-bounce@linux-mips.org
> [mailto:linux-mips-bounce@linux-mips.org]On Behalf Of Zajerko-McKee,
> Nick
> Sent: Friday, September 13, 2002 9:41 AM
> To: 'Gareth'; linux-mips@linux-mips.org
> Subject: RE: Cycle counter
>
>
> Is this under a OS or a single execution? Are there
> interrupts enabled? If
> so, disable them for measurements. (Clock interrupt, serial
> port, etc.).
>
> BTW, most MIPS implementations for OS's and monitors use
> the count/compare
> for their main tick. If you set it to zero you may be
> stepping on someone's
> tick. A better method might be to read the count register
> and read it again
> at the end and do a difference - that way you preserve
> other's values.
>
> Other reasons for a delay: to fetch code (external mem
> ->cache -> cpu) and
> push items onto/off the stack... Theres probably more that
> I can't think of
> right now...
>
> -----Original Message-----
> From: Gareth [mailto:g.c.bransby-99@student.lboro.ac.uk]
> Sent: Friday, September 13, 2002 12:28 PM
> To: linux-mips@linux-mips.org
> 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
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2002-09-16 9:02 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-09-13 16:28 Cycle counter Gareth
2002-09-13 17:10 ` Kevin D. Kissell
2002-09-13 17:10 ` Kevin D. Kissell
[not found] ` <Pine.BSF.4.10.10209130937060.47912-100000@mail.matriplex.com>
2002-09-16 9:02 ` Gareth
-- strict thread matches above, loose matches on Subject: below --
2002-09-13 16:40 Zajerko-McKee, Nick
2002-09-13 16:51 ` Matthew Dharm
2002-09-13 16:51 ` Matthew Dharm
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox