Thread overview
rdtsc
Jul 01, 2002
Roland
Jul 01, 2002
Walter
Jul 01, 2002
Roland
Re: rdtsc and cpu freq calculation
Jul 01, 2002
Roland
Jul 01, 2002
Nic Tiger
Jul 02, 2002
Roland
July 01, 2002
the good news of the day is that DM C++ seems to support asm
rdtsc instruction.
is rdtsc an "official" Pentium instruction now ?
is rdtsc also supported by AMD ?

thanks

roland
July 01, 2002
"Roland" <rv@ronetech.com> wrote in message news:3D202924.E12E9774@ronetech.com...
> the good news of the day is that DM C++ seems to support asm rdtsc instruction.

It's needed!

> is rdtsc an "official" Pentium instruction now ?

I think so.

> is rdtsc also supported by AMD ?

As far as I know it is.



July 01, 2002
Roland a écrit :

> the good news of the day is that DM C++ seems to support asm
> rdtsc instruction.
> is rdtsc an "official" Pentium instruction now ?
> is rdtsc also supported by AMD ?
>
> thanks
>
> roland

I know my previous post (in c++ group) about rdtsc instruction was the
start of a big wave of antousiasm
but i'm sorry, i have to cool it down as things are not so nice, at
least for me.
So, taking the risk of being out of the subject of this newsgroup, i'm
going to ask for some help, here
because it is where the knowledge is.

To test rdtsc instruction i tried to calculate cpu frequency with it. It works fine ...... as long as i'm not comming from boot or Windows !! .....

A little more explanations:

my program is a 32bit DOSX program.
among a lot of other things, it calculates cpu frequency using rdtsc
instruction (see code below).
I reboot the computer, start in pure dos mode,
i run my program
calculated frequency is half the real cpu frequency !
i quit the program
i rerun it
calculated frequency is right !!??

The calculated cpu frequency is wrong (half the exact value) if:
- the pc just rebooted,
- the pc is coming from windows (start/stop/restart in MS-DOS mode),
- the program runs in a Windows box.

Any idea ?

roland

PS:
my goal is not not to calculate the cpu freq.
the goal is to use rdtsc instruction properly, so
understand what's wrong with my code.

-----------------------------------------------------
Here is the code

#define _TICK_CTR_PORT    0x43
#define _TICK_PORT 0x40
#define _BUS_FREQ            1193180ul        //timer clock

static int _gettick() {
//return the current value of the 8254's timer 0
asm {
      xor eax,eax
      out _TICK_CTR_PORT,al    //counter 0 latch
      in al,_TICK_PORT                //lo cp0
      mov ah,al
      in al,_TICK_PORT                //hi cp0
      xchg ah,al
}
    return _EAX;
}

static long _getcpufreq() { //one day this function will have to return
a long long !
    int dummy[1]; dummy[0] = 0;        //because of pushf/popf: force
stack frame, may be not necessary, just a bad habit
    long long rdtsci,rdtscf;

asm {
        pushf            //save if flag
        cli                 //lock interrupts
//loop until timer >= 0x1010
lp0:
        call _gettick
        cmp  eax,1010h
        jb lp0
//now timer >= 0x1010
//now going to loop until timer decrements one, for precision
        dec  eax
        mov  ebx,eax
lp1:
        call _gettick
        cmp  eax,ebx
        ja   lp1
//ok we are now synchronized, now save initial rdtsc value
        rdtsc
        mov  DWORD PTR rdtsci,eax
        mov  DWORD PTR rdtsci[4],edx
//now wait until timer decrements 0x1000
        sub  ebx,1000h
lp2:
        call _gettick
        cmp  eax,ebx
        ja   lp2
//now get final rdtsc value
        rdtsc
        mov  DWORD PTR rdtscf,eax
        mov  DWORD PTR rdtscf[4],edx
//restaure if
        popf
}
    return (long)(((rdtscf-rdtsci)*_BUS_FREQ)/0x1000);
/*
bus_T = 1/bus_Freq
cpu_T = 1/cpu_Freq
0x1000*bus_T = delta_rdtsc*cpu_T
=> cpu_Freq = bus_Freq*delta_rdtsc/0x1000
*/
}





July 01, 2002
Walter a écrit :

> "Roland" <rv@ronetech.com> wrote in message news:3D202924.E12E9774@ronetech.com...
> > the good news of the day is that DM C++ seems to support asm rdtsc instruction.
>
> It's needed!
>
> > is rdtsc an "official" Pentium instruction now ?
>
> I think so.
>
> > is rdtsc also supported by AMD ?
>
> As far as I know it is.

thanks

roland

July 01, 2002
I used little different method for calculating CPU Freq (for Scheduler under
DOSX).

The main idea is that there is interrupt handler (for timer) which every call executes RDTSC instructions (the same place guarantees the same delays), then in case of 1st or 11th time call it stores correspondingly the fist time and the last.

Without modifying timer freq (doesn't work under Win) we have an interval of 550 ms which is sufficient to determine CPU freq.

However under Win it is not very accurate (shows 1045.6 MHz while in DOS -
1006 MHz as supposed to be), but I have never got results that differs in
times (*2 or /2 or other).

Try the EXE in the archive attached, investigate piece of source and report me about behavior you saw.

Nic Tiger.

"Roland" <rv@ronetech.com> wrote in message news:3D209AF4.5F1181C9@ronetech.com...
> Roland a ?crit :
>
> > the good news of the day is that DM C++ seems to support asm
> > rdtsc instruction.
> > is rdtsc an "official" Pentium instruction now ?
> > is rdtsc also supported by AMD ?
> >
> > thanks
> >
> > roland
>
> I know my previous post (in c++ group) about rdtsc instruction was the
> start of a big wave of antousiasm
> but i'm sorry, i have to cool it down as things are not so nice, at
> least for me.
> So, taking the risk of being out of the subject of this newsgroup, i'm
> going to ask for some help, here
> because it is where the knowledge is.
>
> To test rdtsc instruction i tried to calculate cpu frequency with it. It works fine ...... as long as i'm not comming from boot or Windows !! .....
>
> A little more explanations:
>
> my program is a 32bit DOSX program.
> among a lot of other things, it calculates cpu frequency using rdtsc
> instruction (see code below).
> I reboot the computer, start in pure dos mode,
> i run my program
> calculated frequency is half the real cpu frequency !
> i quit the program
> i rerun it
> calculated frequency is right !!??
>
> The calculated cpu frequency is wrong (half the exact value) if:
> - the pc just rebooted,
> - the pc is coming from windows (start/stop/restart in MS-DOS mode),
> - the program runs in a Windows box.
>
> Any idea ?
>
> roland
>
> PS:
> my goal is not not to calculate the cpu freq.
> the goal is to use rdtsc instruction properly, so
> understand what's wrong with my code.
>
> -----------------------------------------------------
> Here is the code
>
> #define _TICK_CTR_PORT    0x43
> #define _TICK_PORT 0x40
> #define _BUS_FREQ            1193180ul        file://timer clock
>
> static int _gettick() {
> file://return the current value of the 8254's timer 0
> asm {
>       xor eax,eax
>       out _TICK_CTR_PORT,al    file://counter 0 latch
>       in al,_TICK_PORT                file://lo cp0
>       mov ah,al
>       in al,_TICK_PORT                file://hi cp0
>       xchg ah,al
> }
>     return _EAX;
> }
>
> static long _getcpufreq() { file://one day this function will have to
return
> a long long !
>     int dummy[1]; dummy[0] = 0;        file://because of pushf/popf: force
> stack frame, may be not necessary, just a bad habit
>     long long rdtsci,rdtscf;
>
> asm {
>         pushf            file://save if flag
>         cli                 file://lock interrupts
> file://loop until timer >= 0x1010
> lp0:
>         call _gettick
>         cmp  eax,1010h
>         jb lp0
> file://now timer >= 0x1010
> file://now going to loop until timer decrements one, for precision
>         dec  eax
>         mov  ebx,eax
> lp1:
>         call _gettick
>         cmp  eax,ebx
>         ja   lp1
> file://ok we are now synchronized, now save initial rdtsc value
>         rdtsc
>         mov  DWORD PTR rdtsci,eax
>         mov  DWORD PTR rdtsci[4],edx
> file://now wait until timer decrements 0x1000
>         sub  ebx,1000h
> lp2:
>         call _gettick
>         cmp  eax,ebx
>         ja   lp2
> file://now get final rdtsc value
>         rdtsc
>         mov  DWORD PTR rdtscf,eax
>         mov  DWORD PTR rdtscf[4],edx
> file://restaure if
>         popf
> }
>     return (long)(((rdtscf-rdtsci)*_BUS_FREQ)/0x1000);
> /*
> bus_T = 1/bus_Freq
> cpu_T = 1/cpu_Freq
> 0x1000*bus_T = delta_rdtsc*cpu_T
> => cpu_Freq = bus_Freq*delta_rdtsc/0x1000
> */
> }
>
>
>
>
>



July 02, 2002
many thanks again

i will let you informed (can be a little long)

roland


Nic Tiger a écrit :

> I used little different method for calculating CPU Freq (for Scheduler under
> DOSX).
>
> The main idea is that there is interrupt handler (for timer) which every call executes RDTSC instructions (the same place guarantees the same delays), then in case of 1st or 11th time call it stores correspondingly the fist time and the last.
>
> Without modifying timer freq (doesn't work under Win) we have an interval of 550 ms which is sufficient to determine CPU freq.
>
> However under Win it is not very accurate (shows 1045.6 MHz while in DOS -
> 1006 MHz as supposed to be), but I have never got results that differs in
> times (*2 or /2 or other).
>
> Try the EXE in the archive attached, investigate piece of source and report me about behavior you saw.
>
> Nic Tiger.
>
> "Roland" <rv@ronetech.com> wrote in message news:3D209AF4.5F1181C9@ronetech.com...
> > Roland a ?crit :
> >
> > > the good news of the day is that DM C++ seems to support asm
> > > rdtsc instruction.
> > > is rdtsc an "official" Pentium instruction now ?
> > > is rdtsc also supported by AMD ?
> > >
> > > thanks
> > >
> > > roland
> >
> > I know my previous post (in c++ group) about rdtsc instruction was the
> > start of a big wave of antousiasm
> > but i'm sorry, i have to cool it down as things are not so nice, at
> > least for me.
> > So, taking the risk of being out of the subject of this newsgroup, i'm
> > going to ask for some help, here
> > because it is where the knowledge is.
> >
> > To test rdtsc instruction i tried to calculate cpu frequency with it. It works fine ...... as long as i'm not comming from boot or Windows !! .....
> >
> > A little more explanations:
> >
> > my program is a 32bit DOSX program.
> > among a lot of other things, it calculates cpu frequency using rdtsc
> > instruction (see code below).
> > I reboot the computer, start in pure dos mode,
> > i run my program
> > calculated frequency is half the real cpu frequency !
> > i quit the program
> > i rerun it
> > calculated frequency is right !!??
> >
> > The calculated cpu frequency is wrong (half the exact value) if:
> > - the pc just rebooted,
> > - the pc is coming from windows (start/stop/restart in MS-DOS mode),
> > - the program runs in a Windows box.
> >
> > Any idea ?
> >
> > roland
> >
> > PS:
> > my goal is not not to calculate the cpu freq.
> > the goal is to use rdtsc instruction properly, so
> > understand what's wrong with my code.
> >
> > -----------------------------------------------------
> > Here is the code
> >
> > #define _TICK_CTR_PORT    0x43
> > #define _TICK_PORT 0x40
> > #define _BUS_FREQ            1193180ul        file://timer clock
> >
> > static int _gettick() {
> > file://return the current value of the 8254's timer 0
> > asm {
> >       xor eax,eax
> >       out _TICK_CTR_PORT,al    file://counter 0 latch
> >       in al,_TICK_PORT                file://lo cp0
> >       mov ah,al
> >       in al,_TICK_PORT                file://hi cp0
> >       xchg ah,al
> > }
> >     return _EAX;
> > }
> >
> > static long _getcpufreq() { file://one day this function will have to
> return
> > a long long !
> >     int dummy[1]; dummy[0] = 0;        file://because of pushf/popf: force
> > stack frame, may be not necessary, just a bad habit
> >     long long rdtsci,rdtscf;
> >
> > asm {
> >         pushf            file://save if flag
> >         cli                 file://lock interrupts
> > file://loop until timer >= 0x1010
> > lp0:
> >         call _gettick
> >         cmp  eax,1010h
> >         jb lp0
> > file://now timer >= 0x1010
> > file://now going to loop until timer decrements one, for precision
> >         dec  eax
> >         mov  ebx,eax
> > lp1:
> >         call _gettick
> >         cmp  eax,ebx
> >         ja   lp1
> > file://ok we are now synchronized, now save initial rdtsc value
> >         rdtsc
> >         mov  DWORD PTR rdtsci,eax
> >         mov  DWORD PTR rdtsci[4],edx
> > file://now wait until timer decrements 0x1000
> >         sub  ebx,1000h
> > lp2:
> >         call _gettick
> >         cmp  eax,ebx
> >         ja   lp2
> > file://now get final rdtsc value
> >         rdtsc
> >         mov  DWORD PTR rdtscf,eax
> >         mov  DWORD PTR rdtscf[4],edx
> > file://restaure if
> >         popf
> > }
> >     return (long)(((rdtscf-rdtsci)*_BUS_FREQ)/0x1000);
> > /*
> > bus_T = 1/bus_Freq
> > cpu_T = 1/cpu_Freq
> > 0x1000*bus_T = delta_rdtsc*cpu_T
> > => cpu_Freq = bus_Freq*delta_rdtsc/0x1000
> > */
> > }
> >
> >
> >
> >
> >
>
>                   Name: MES_TSC.ZIP
>    MES_TSC.ZIP    Type: Zip Compressed Data (application/x-zip-compressed)
>               Encoding: x-uuencode