Telling CPU Speed (for the FAQ)

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
virusx

Re:Telling CPU Speed (for the FAQ)

Post by virusx »

Candy wrote: And just for a hint, try searching the processor ID string, it usually contains the speed too ;) (note, the speed, not the frequency)
what does that mean? Where can we find the speed. I am hearing it for first time.

:-\
DennisCGc

Re:Telling CPU Speed (for the FAQ)

Post by DennisCGc »

algorithm: multiply the value you get by 6, add 50, chop off the last 2 decimals, divide by 6, and use that value. This rounds off to 1333 / 1350 / 1366 / 1387 / 1400 etc. so you get a "nice" speed instead of 1402.123 mhz
I like that more than the "nice" speed ;)
Seriously, because I program in assembly, I get (according to that measured speed) 1402 ;)
DennisCGc

Re:Telling CPU Speed (for the FAQ)

Post by DennisCGc »

And how to detect the cpu speed for 486's ?
(no, not the 386's because my OS doesn't seem to support it ::) )
Curufir

Re:Telling CPU Speed (for the FAQ)

Post by Curufir »

DennisCGc wrote: And how to detect the cpu speed for 486's ?
Without the internal counter you'll have to do it the old fashioned way and measure the time it takes to execute a piece of code with a well known cycle count. It's tricky to produce a piece of code like that with all the caching mechanisms, but not that hard.

This isn't going to provide you with a hugely accurate speed reading, but it should be sufficient to deliver a decent estimate if you round up to the nearest production speed.
DennisCGc

Re:Telling CPU Speed (for the FAQ)

Post by DennisCGc »

Without the internal counter you'll have to do it the old fashioned way and measure the time it takes to execute a piece of code with a well known cycle count. It's tricky to produce a piece of code like that with all the caching mechanisms, but not that hard
Any suggestions ? ???
Could:

Code: Select all

INC  ECX
be helpful ?
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Telling CPU Speed (for the FAQ)

Post by Candy »

DennisCGc wrote: Any suggestions ? ???
Could:

Code: Select all

INC  ECX
be helpful ?
sth like

Code: Select all

xor ecx, ecx
jmpl:
inc ecx
jmp jmpl

Code: Select all

void count() {
   register_handler(&count_handler);
   wait_for_pulse();
   start_thread();
}

count_handler () {
   read_ecx_count_off_the_stack();
   stop_thread();
   return ecx_count * cycle count;
}
but of course, this stuff is highly dependant on how you do your timer stuff.
DennisCGc

Re:Telling CPU Speed (for the FAQ)

Post by DennisCGc »

Anyway, just found a method to do that.
This code is not accurate, maybe I should adjust the value for dividing.
And I think the total MHz on very new system will be very inaccurate, but this code is made for 486's,
If you're interested, you can post it in here ;)
So I can eventually post it in this thread :)
(And maybe it can be used for the WikiFAQ ;D (heh, I wish))
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Telling CPU Speed (for the FAQ)

Post by Pype.Clicker »

well, post it and we'll see :)
DennisCGc

Re:Telling CPU Speed (for the FAQ)

Post by DennisCGc »

Pype.Clicker wrote: well, post it and we'll see :)
Okay :)
NOTE: could lead to inaccurate measurements. Tested on my P1 and it worked (yes, tested also on another P1, with another MHz)

Code: Select all

;divider = 3334
;assumes that IRQ0_COUNT will change after the timer interrupt is called.
;PIT must be set to 100 hz.

   mov  ebx,[irq0_count]
irq0loop:
   cmp  ebx,[irq0_count]
   jz     irq0loop
;timer interrupt just occured, start!
  mov  ebx, [irq0_count]
  add   ebx,2
  xor   ecx,ecx
cpu_loop:
  inc   ecx
  cmp  ebx,[irq0_count]
  jnz   cpu_loop
;end loop
  xor  edx,edx
  mov  eax,ecx
  mov  ecx,3334
  idiv   ecx
;eax contains the MHZ :)
Note: if it's wrong on 486's, please recalculate it :(
I think the values would be the same
And another thing: if the MHZ is totally different on your P1, please change the

Code: Select all

 add ebx,2
to

Code: Select all

 inc ebx
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Telling CPU Speed (for the FAQ)

Post by Pype.Clicker »

The most 'precise' PIT dividers and clock speed i can find:
200 5965.9 Hz
5966 5.00008ms 199.996647670131 Hz
11932 10000.16... us (99,998 Hz)
13125 11.000016 ms
26250 22.000033 ms
59659 50 ms 50000 us 20 Hz
So indeed, using '20Hz' PIT could be the best if one can perform exact CPU speed detection *before* task switching is in place (imho, it wouldn't be nice to have a system which can only schedule 20 tasks a second as our screens goes up to 60 frames a second :-/)

Running the timer at 5965.9 Hz would mean that after 59659 ticks occured, you know 10 seconds have exactly elapsed ... though it might be too long for a calibration.
DennisCGc

Re:Telling CPU Speed (for the FAQ)

Post by DennisCGc »

But did you test my code ? ::)
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Telling CPU Speed (for the FAQ)

Post by Pype.Clicker »

hum. not yet (i'm not on holiday in case you might wonder)
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Telling CPU Speed (for the FAQ)

Post by Pype.Clicker »

hehe ... i might have found something of interrest ... a technique that theorically do not require interrupt handlers to be set up :)

it's on the Wiki page ...
FlashBurn

Re:Telling CPU Speed (for the FAQ)

Post by FlashBurn »

I can not test the your code on a machine <1GHz, but on my XP1800+ it gives me 1646MHz. So it is not that accurate, but it seems to work. I?ve written the code in assembly and there I also have the problem that I don?t know how to do a multiply with a 64bit integer. This is the code if anyone is interessed in:

Code: Select all

cli
   
   mov al,34h
   out 43h,al
   xor al,al
   out 40h,al
   out 40h,al
   
   rdtsc
   mov [stsc],edx
   mov [stsc+4],eax
   
   mov ecx,1000h
   
.loop_tsc
   rdtsc
   mov [etsc],edx
   mov [etsc+4],eax
   
   dec ecx
   jnz .loop_tsc
   
   mov al,4
   out 43h,al
   
   in al,40h
   mov [blow],al
   in al,40h
   mov [bhigh],al
   
   movzx eax,byte[bhigh]
   shl eax,8
   movzx ebx,byte[blow]
   add ebx,eax
   mov eax,10000h
   sub eax,ebx
   mov [ticks],eax
   
   mov edx,[etsc]
   mov eax,[etsc+4]
   mov ebx,[stsc]
   sub eax,[stsc+4]
   sbb edx,ebx
   
   mov ebx,1193180
   mul ebx
   mov ebx,[ticks]
   div ebx
   
   call dec2ascii_str, eax
   
   sti
The "dec2ascii_str" function is a function which prints out the dec number of the parameter which is given.

Edit::

Corrected my code so that it now gives the correct value.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Telling CPU Speed (for the FAQ)

Post by Pype.Clicker »

and does it give better results when you initializes ecx with higher values ?

The algorithm i was thinking about was

Code: Select all

    loop_length=0x1000;
    do {
       Mhz=compute_mhz(loop_length,&elapsed_ticks);
       loop_length*=2;
    } while(elapsed_ticks < 0x4000);
thanks a lot for giving it a try, however :)
Post Reply