[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [rtl] Problems with RDTSC examples posted here recently



On Sat, Nov 03, 2001 at 02:03:12AM +0000, ndrez@att.net wrote:
> Method2 is broken because it gives erroneous results.  
> In my original post I presented a small program that 
> called three different versions of a RDTSC functions 
> (1,2,2A) and only method 1 gave results that were in any 
> posssible way correct.  Since these are three different 
> functions, there can't be any optimization issues 
> between the source code in the three functions and it's 
> not at all obvious -- at least to me -- where 
> a "volatile" declaration could be put.  If someone could 
> post a modified version of my program in method 2 or 
> method 2a worked, I'd be very grateful.


> > > ---method1---
> > > __inline__ unsigned long long int rdtsc(void)
> > > {
> > > 	unsigned long long int x;
> > > 	__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
> > > 	return x;
> > > }
> > > 
> > > 
> > > ---method2A---
> > > __inline__ unsigned long long int hwtime(void)
> > > {
> > > 	unsigned long long int x;
> > > 	__asm__("rdtsc\n\t"
> > > 		"mov %%edx, %%ecx\n\t"
> > > 		:"=A" (x));
> > > 	return x;
> > > }

Things, severally:

1) Use __volatile__, not volatile. Just an ANISism for clarity.

2) The mov is, in practice, as much use as a chocolate teapot. You're
achieving absolutely nada.

3) In the case you're using 2A, [It's been a long time since I did any
"serious" assembly], don't you need to give some clobber registers?
Specifically, something like:

---method2A-clobber---
__inline__ unsigned long long int hwtime(void)
{
 unsigned long long int x;
 __asm__("rdtsc\n\t"
          "mov %%edx, %%ecx\n\t"
          :"=A" (x)
	  :
          : "ecx");
  return x;
}

Or %ecx, or whatever it is. Can't remember, as I'm not using it.

In the end, here's some actual code I'm now using:

/* Ripped straight out of "vanilla" kernel */
#define rdtscll(x) \
        __asm__ __volatile__ ("rdtsc" : "=A" (x))

<snip>
long long int time_blocked,counter0,counter1;
do_some_funky_init_stuff();
        while (1) {
                rdtscll(counter0);
		pthread_wait_np ();
                rdtscll(counter1);
		time_blocked = counter1-counter0;
		rtf_put(fifo_out, (char *) &time_blocked,sizeof(time_blocked));
	}
</snip>

Obviously, that achieves very little except to tell you what _other_
processes in your system are doing to aid in the jitter of your piece
of code.
But still, it gets the point across, yes?

Gary (-;	

PS Norm, you've been instrumental in getting me this far, and thanks
(=