Getting CPU speed

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.
Assembler

Getting CPU speed

Post by Assembler »

Hi,
i want to get the cpu speed to be used my library.
i know the method descibed in the wiki, but i think there is a more accurate method as the one used by linux.
i think its implemented by FSB & Multiplier (x10).
so, do any one have any idea ?

Thanks,
Assembler
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:Getting CPU speed

Post by Pype.Clicker »

Afaik, linux mainly detects the Bogomips -- a measure of "how fast your computer can do nothing" that is used for small delays.

Or are you meaning something else ?

can you precise what "FSB" is too ? i thought it would be for "Front Bus Speed", but that doesn't stick to your acronym.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Getting CPU speed

Post by Candy »

Pype.Clicker wrote: can you precise what "FSB" is too ? i thought it would be for "Front Bus Speed", but that doesn't stick to your acronym.
FSB stands for Front Side Bus, which is the bus the CPU communicates over with the North Bridge (or some hub in intel-slang).
Assembler

Re:Getting CPU speed

Post by Assembler »

Yes, i mean Front Side Bus, which can be used to overclock your cpu speed.
For more information about overclocking you would better check this : http://www.overclockersclub.com/overclockingfaq.php
here is what you can find on site :

How does FSB determine CPU speed?
CPU speed is determined by the following formula:
   FSB x Multiplier = CPU Speed
For example, if you had a FSB setting of 133MHz and a 10x Multiplier, your CPU speed would be 1330MHz or 1.33GHz.

i've looked in the linux kernel source 2.6.x and here is a snapshot from a file inside arch/i386/kernel/ caled speedstep-lib.c as i remember.

Code: Select all

/*********************************************************************
 *                   GET PROCESSOR CORE SPEED IN KHZ                 *
 *********************************************************************/

static unsigned int pentium3_get_frequency (unsigned int processor)
{
        /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */
   struct {
      unsigned int ratio;   /* Frequency Multiplier (x10) */
      u8 bitmap;           /* power on configuration bits
                  [27, 25:22] (in MSR 0x2a) */
   } msr_decode_mult [] = {
      { 30, 0x01 },
      { 35, 0x05 },
      { 40, 0x02 },
      { 45, 0x06 },
      { 50, 0x00 },
      { 55, 0x04 },
      { 60, 0x0b },
      { 65, 0x0f },
      { 70, 0x09 },
      { 75, 0x0d },
      { 80, 0x0a },
      { 85, 0x26 },
      { 90, 0x20 },
      { 100, 0x2b },
      { 0, 0xff }     /* error or unknown value */
   };

   /* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */
   struct {
      unsigned int value;     /* Front Side Bus speed in MHz */
      u8 bitmap;              /* power on configuration bits [18: 19]
                  (in MSR 0x2a) */
   } msr_decode_fsb [] = {
      {  66, 0x0 },
      { 100, 0x2 },
      { 133, 0x1 },
      {   0, 0xff}
   };

   u32     msr_lo, msr_tmp;
   int     i = 0, j = 0;

   /* read MSR 0x2a - we only need the low 32 bits */
   rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
   dprintk("P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
   msr_tmp = msr_lo;

   /* decode the FSB */
   msr_tmp &= 0x00c0000;
   msr_tmp >>= 18;
   while (msr_tmp != msr_decode_fsb[i].bitmap) {
      if (msr_decode_fsb[i].bitmap == 0xff)
         return 0;
      i++;
   }

   /* decode the multiplier */
   if (processor == SPEEDSTEP_PROCESSOR_PIII_C_EARLY) {
      dprintk("workaround for early PIIIs\n");
      msr_lo &= 0x03c00000;
   } else
      msr_lo &= 0x0bc00000;
   msr_lo >>= 22;
   while (msr_lo != msr_decode_mult[j].bitmap) {
      if (msr_decode_mult[j].bitmap == 0xff)
         return 0;
      j++;
   }

   dprintk("speed is %u\n", (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100));

   return (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100);
}
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Getting CPU speed

Post by Candy »

Assembler wrote: here is what you can find on site :

How does FSB determine CPU speed?
CPU speed is determined by the following formula:
???FSB x Multiplier = CPU Speed
For example, if you had a FSB setting of 133MHz and a 10x Multiplier, your CPU speed would be 1330MHz or 1.33GHz.
The most common way to figure out how many cycles your processor makes in a second, is to count them during a second. For accuracy this is usually done with 1/20th second and then multiplied by 20, so you don't have interrupt overhead.
i've looked in the linux kernel source 2.6.x and here is a snapshot from a file inside arch/i386/kernel/ caled speedstep-lib.c as i remember.
Speedstep works on ... Intel Speedstep-capable processors! *surprise*.

That code will only work if you have that kind of processor. There'll be similar stuff in AMD processors (PowerNow) and it's not available on old ones.
Assembler

Re:Getting CPU speed

Post by Assembler »

Candy wrote:
The most common way to figure out how many cycles your processor makes in a second, is to count them during a second. For accuracy this is usually done with 1/20th second and then multiplied by 20, so you don't have interrupt overhead.

Speedstep works on ... Intel Speedstep-capable processors! *surprise*.

That code will only work if you have that kind of processor. There'll be similar stuff in AMD processors (PowerNow) and it's not available on old ones.
yes i know, that this method is processor specific, which needs to detect the processor's type first, but why would linus use it unless its better or more accurate ?
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Getting CPU speed

Post by Candy »

Assembler wrote: yes i know, that this method is processor specific, which needs to detect the processor's type first, but why would linus use it unless its better or more accurate ?
Because it's more functional. Speedstep and powernow cpu's can change clock-speed at runtime, so you need to run this code a lot. If you're going to run it a lot, you don't want it to take 50 milliseconds of full cpu time each time.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Getting CPU speed

Post by Solar »

@ Assembler:

I fear you're throwing too many things into the same pot.

One, CPU speed detection by the OS is completely unrelated to overclocking. Setting the FSB (the speed at which your CPU talks to the northbridge) and the clock multiplier (applied to the FSB clock to get the internal CPU clock) is done via jumpers or BIOS switches. Both factors don't matter for an OS.

Most of the timing in an operating system is done via interrupts. (You will agree that "waiting loops" are a little bit C-64 in the age of multitasking OS's.)

For some fine-tuning, however, an OS must know how fast the CPU is it runs on. That's the BogoMips that Linux is calculating.

Yet again completely unrelated is the SpeedStep feature of some CPUs, which allows to reduce the clock speed in idle periods - this is done to preserve memory.

Perhaps it would be helpful if you would tell us exactly what you are trying to do...
Every good solution is obvious once you've found it.
Assembler

Re:Getting CPU speed

Post by Assembler »

Solar wrote: Perhaps it would be helpful if you would tell us exactly what you are trying to do...
To determine the speed on the CPU from my library and pass it to the kernel.
Both ways can determine the CPU speed.

http://libosdk.berlios.de
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Getting CPU speed

Post by Solar »

Nice page. Misses a summary on what your libOSDK is about, but smart ones could deduce that from the name.

There's actually an FAQ on Linux' way to do this - the BogoMips FAQ. Note that this value only makes sense if it comes with a wait-loop that can be calibrated with the value...
Every good solution is obvious once you've found it.
User avatar
kataklinger
Member
Member
Posts: 381
Joined: Fri Nov 04, 2005 12:00 am
Location: Serbia

Re:Getting CPU speed

Post by kataklinger »

Solar wrote: Most of the timing in an operating system is done via interrupts. (You will agree that "waiting loops" are a little bit C-64 in the age of multitasking OS's.)
C=64? There's few 16-bit multitasking OSes for C=64, but you need to have CMD SuperCPU to run them. ;)
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:Getting CPU speed

Post by Pype.Clicker »

Solar wrote: Most of the timing in an operating system is done via interrupts. (You will agree that "waiting loops" are a little bit C=64 in the age of multitasking OS's.)
not agreeing.
Sometimes, kernel code (usually drivers) requires very short (smaller than a clock tick) and rather precise delay (...). The [tt]udelay()[/tt] function is implemented as a loop that knows how many iterations can be executed in a given period of time. Because the kernel knows how many loops the processor can complete in a second (see the sidebar on BogoMips), the udelay function simply scales that value to the correct number of iteration for the given delay.
-- Ch. 10 (Timers and Time Management), "Linux Kernel Development, 2nd Ed.", Robert Love (0-672-32720-1)
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Getting CPU speed

Post by Solar »

::)

I said "most", and one sentence later I mentioned the necessary "fine-tuning" (especially in drivers).

Can't you leave a statement alone just once? :D
Every good solution is obvious once you've found it.
srg

Re:Getting CPU speed

Post by srg »

One thing I didn't understand from the BogoMips FAQ was the algorithm to actually calculate it. It points to the Linux Kernel code but I've always found the linux kernel code to be about as clear as mud.
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:Getting CPU speed

Post by Pype.Clicker »

Solar wrote: Can't you leave a statement alone just once? :D
Sorry. I shouldn't post replies in a rush 5 minutes before leaving the office ... :P
Post Reply