C Board  

Go Back   C Board > Platform Specific Boards > Linux Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 03-14-2008, 12:20 PM   #1
Registered User
 
Join Date: Mar 2008
Posts: 15
Determining CPU frequency

Hi,

is there any way one can determine the current CPU frequency?
I was trying to figure out a way to do this but couldn't find a way that works. My approach was to use the TSC (Time Stamp Counter), but with the tickless feature in the kernel the TSC gets unstable and can't be used for frequency calculation anymore.

Here's a draft of this idea (though on my systems with tickless enabled the calculated frequency is absolutely wrong):
Code:
#include <stdio.h>
#include <sys/time.h>
#include <string.h>
#include <unistd.h>

unsigned long long int rdtsc(void)
{
        unsigned long long int x;
        __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
        return x;
}

int main()
{
        struct timezone tz;
        struct timeval tvstart, tvstop;
        unsigned long long int cycles[2];
        unsigned long microseconds;
        int mhz;

        memset(&tz, 0, sizeof(tz));

        gettimeofday(&tvstart, &tz);
        cycles[0] = rdtsc();
        gettimeofday(&tvstart, &tz);

        usleep(250000);

        gettimeofday(&tvstop, &tz);
        cycles[1] = rdtsc();
        gettimeofday(&tvstop, &tz);

        microseconds = ((tvstop.tv_sec-tvstart.tv_sec)*1000000) + (tvstop.tv_usec-tvstart.tv_usec);

        mhz = (int) (cycles[1]-cycles[0]) / microseconds;

        printf("%i MHz\n",mhz);

  return 0;
}
The idea is to read the TSC, wait a small amount of time and read the TSC again. TSCnow-TSCstart / waited_time will return the CPU frequency provided the TSC is stable.
With tickless this gets all messed up and I can't come up with any other idea...

Peter
pgzh is offline   Reply With Quote
Old 03-14-2008, 01:45 PM   #2
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,768
Quote:
Originally Posted by pgzh View Post
The idea is to read the TSC, wait a small amount of time and read the TSC again. TSCnow-TSCstart / waited_time will return the CPU frequency provided the TSC is stable.
In fact, this is exactly how Linux computes the frequency...

If you're on Linux, just read the frequency from /proc/cpuinfo. Calculating it yourself on a live system is going to be impossible.

I thought maybe the CPUID instruction would give you the processor frequency, but it doesn't seem to. You might also be able to query the BIOS somehow, but I doubt you can do that from a booted operating system.
brewbuck is offline   Reply With Quote
Old 03-14-2008, 03:38 PM   #3
Registered User
 
Join Date: Mar 2008
Posts: 15
Are you sure Linux reads the TSC for frequency calculation? The cpu mhz info in /proc/cpuinfo changes when using cpufreq with ondemand, but the TSC does not tick constant if tickless is enabled - and therefore it's impossible to calculate the frequency after booting up with the TSC.

Reading /proc/cpuinfo seems like quite a cheap solution, but I really can't think of any better way to get the cpu frequency.

I don't know if MS Windows implements something comparable to the tickless feature of Linux, because there are lots of tools for Windows that can calculate the cpu frequency quite accurately. Or maybe there is another way to get the current cpu mhz?

Anyway - thanks for the tip!

Peter
pgzh is offline   Reply With Quote
Old 03-14-2008, 03:42 PM   #4
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,768
Quote:
Originally Posted by pgzh View Post
Are you sure Linux reads the TSC for frequency calculation? The cpu mhz info in /proc/cpuinfo changes when using cpufreq with ondemand, but the TSC does not tick constant if tickless is enabled - and therefore it's impossible to calculate the frequency after booting up with the TSC.
I based my statement on code I see in Linux 2.4.15. It may be different now in 2.6.

Quote:
Reading /proc/cpuinfo seems like quite a cheap solution, but I really can't think of any better way to get the cpu frequency.
I don't think you can do any better. Linux /proc is unusual because it generates human-readable output. Other UNIX systems produce binary structures which are easier to deal with. On Linux you are left calling fgets() and parsing lines. Sucks for the programmer but makes it easier for the user who just wants to "cat /proc/whatever".
brewbuck is offline   Reply With Quote
Old 03-15-2008, 09:49 AM   #5
Registered User
 
Join Date: Mar 2008
Posts: 15
Where exactly in the Linux source code did you look? Maybe I can look for the way this is handled in 2.6 myself.

Peter
pgzh is offline   Reply With Quote
Old 03-15-2008, 10:19 AM   #6
Registered User
 
Codeplug's Avatar
 
Join Date: Mar 2003
Posts: 3,903
Here proc sources:
http://lxr.linux.no/linux/arch/i386/...pu/proc.c#L111

gg
Codeplug is offline   Reply With Quote
Old 03-17-2008, 10:18 AM   #7
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,768
Quote:
Originally Posted by pgzh View Post
Where exactly in the Linux source code did you look? Maybe I can look for the way this is handled in 2.6 myself.
The (quite confusing) algorithm is located in arch/i386/kernel/time.c (but that was 2.4)
brewbuck is offline   Reply With Quote
Old 03-17-2008, 10:34 AM   #8
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
Quote:
Are you sure Linux reads the TSC for frequency calculation?
If it should have ANY chance to figure out the speed of a modern x86 CPU, yes. There is realistically no other method that works. [Yes, you can run loops, and based on "clocks per instruction" calculate what the processor is running at - but you need to be VERY careful, because different processor models will have different levels of parallelism and different clock counts for the same instructions].

Quote:
but the TSC does not tick constant if tickless is enabled
I'm pretty sure this is NOT related to tickless. tickless just means that the machine will not have a x Hz timer tick that interrupts x times per second, but rather set up the timer interrupt to interrupt "when it's needed" [e.g. if the next thing waiting is waiting for 250000 microseconds to elapse, then set a timer for 250 us from now]. Since it's very likely that waiting processes aren't waiting for the next timer tick most of the time, it's a good saving to just set it to tick when there's actually something waiting for that time to come up. [It is rather complicated to implement a tickless kernel, however, which is why it wasn't implemented before].

If TSC is varying, then it's most likely because you are running the power management and it detects idle CPU and stops/slows down the CPU. This SHOULD happen whether you are running with or without ticks, however.

--
Mats
__________________
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
matsp is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
questions on multiple thread programming lehe C Programming 11 03-27-2009 07:44 AM
Upgrading my old CPU (for another old one!) foxman Tech Board 16 01-11-2008 05:41 PM
Can you still view the bios screen with a bad CPU? HyperCreep Tech Board 4 12-31-2006 06:57 PM
CPU temp PING Tech Board 5 01-28-2006 06:25 AM
determining frequency lakai02 C Programming 4 10-03-2002 05:03 PM


All times are GMT -6. The time now is 02:13 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22