Solved

how to measure cpu time cpp

Posted on 2009-05-17
18
1,399 Views
Last Modified: 2013-12-10
how to measure cpu time cpp
05/18/09 - added C++ zone - Callandor

Open in new window

0
Comment
Question by:kalech
  • 4
  • 2
  • 2
  • +4
18 Comments
 

Author Comment

by:kalech
ID: 24410109
I try to measure the cpu time of an exponential function in Cpp in Windows XP. It is important for me to measure only the function time ignoring the I/O time and ignoring other processes. I am looking for an API that I can use start and end, and it measure the cpu between them so I acan measure only the cpu time of the function.
0
 
LVL 69

Expert Comment

by:Callandor
ID: 24411703
You may want to use the clock() function - see http://www.physicsforums.com/showthread.php?t=224989
0
 
LVL 1

Expert Comment

by:Devoney
ID: 24412180
I think you want to use the 'rdtsc' instruction (0x0F31). This will fill EAX:EDX with a 64 bit value specifying the current clock cycle. If you request it twice and extract these values you have the difference in clock cycles that was needed to perform the operation between your timepoints.

You could also use DWORD WINAPI GetTickCount(void); which returns the miliseconds since system startup, you could use this to for timing an operation.

The best way to go is executing your exponential function before windows has booted. Or in a virtual machine (VmWare). I have experienced that timings in a virtual machine are not effected by other processes in the windows host (handy for quickly testing). So compile your code with the timing of your choice in a console mode application and run that by using a bootdisk of somekind (floppy, virtual floppy, CD-ROM). Otherwise you will never know how many CPU clocks where spent on other processes running in the background. Example in assembly about RDTSC I have once written is included.

// CPUSpeed.cpp : Defines the entry point for the console application.

#include <stdafx.h>

#include <iostream>

#include <string>

#include <Windows.h>

#include <stdio.h>

#include <winbase.h>

#include <winuser.h>
 

using namespace std;
 

int _tmain(int argc, _TCHAR* argv[])

{

	system("cls"); //Clean the console screen

	SetConsoleTitleA("CPU Current Working Speed - by Devoney"); //Set the title of the console screen

	__int64 Answer = 0; //Make a 64-bit, way to large, variable.
 

	//Output some text describing the program and offering the user to choose the time interval.

	cout << "CPU Current Working Speed\n\nThis program will measure how many clockcycles have passed during a time interval. Then it will calculate how many clockcycles this have been per second and convert the value in Mhz. The program will NOT measure the speed of the CPU in Ghz at which is clocked on, but will measure it's current working speed while executing this program.\n\n";

	cout << "Select your time interval: \n1. 1sec\n2. 2sec\n3. 5sec\n4. 10sec\n5. 30sec\n\nAnswer: ";

	

	cin >> Answer; //retrieve answer
 

	//Check which answer was given and redefine Answer for later use in the Sleep() function.

	//Notice that their is no error handler when wrong input is given.

	if(Answer == 1)

	{

		Answer = 1000;

	}

	if(Answer == 2)

	{

		Answer = 2000;

	}

		if(Answer == 3)

	{

		Answer = 5000;

	}

	if(Answer == 4)

	{

		Answer = 10000;

	}

	if(Answer == 5)

	{

		Answer = 30000;

	}
 

	//Initialize 3 64-bit variables, the returned value of RDTSC is 64 bit. We need to obtain it twice and substract them.

	__int64 unsigned BeginClock = 0;

	__int64 unsigned EndClock = 0;

	__int64 unsigned Speed = 0;

	cout << "\nVariables initialized...\n";

	

	//Try to set the priority of the program to the highest possible, realtime.

	if(SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS))

	{

		cout << "Priority Class Set To Realtime...\n";

	}

	else

	{

		cout << "Priority Class Could Not Be Set To Realtime...\n";

	}
 

	cout << "Waiting for interval to pass...\n\n";

	_asm

	{

		RDTSC //Execute the opcode RDTSC

		mov DWORD PTR SS:[BeginClock], EAX //Move the bytes stored in EAX to the variable BeginClock

		mov DWORD PTR SS:[BeginClock+4], EDX //Move the most significant bytes stored in EDX to BeginClock

	}

	

		Sleep(Answer); //Wait the chosen amount of time
 

	_asm

	{

		//Again use RDTSC

		RDTSC

		mov DWORD PTR SS:[EndClock], EAX

		mov DWORD PTR SS:[EndClock+4], EDX

	}
 
 

	Speed  = (EndClock - BeginClock); //Substract the two RDTSC values to obtain the clockcycles done in the time interval

	cout << "Clockcycles since reset (before interval): " << BeginClock << "\nClockcycles since reset (after interval):  " << EndClock << "\nAmount of Clockcycles after substraction:  " << Speed << "\n";

	Speed = Speed / (1000000 * (Answer/1000)); //Convert the clockcycles to Mhz using the time interval and 1,000,000 constant because otherwise the speed is given in Hz

	cout << "Measured CPU Speed: " << Speed << "Mhz\nProgram Terminated\n";

	return 0; //Exit the program

}

Open in new window

0
 
LVL 1

Expert Comment

by:Devoney
ID: 24412241
The example code is VS2005 ;) Is their an option to edit a comment?
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 24414055
'clock()' won't help much, since it does only yield a time difference, not the time a process has been utilizing the CPU during that period. 'GetProcessTimes()' (http://msdn.microsoft.com/en-us/library/ms683223.aspx) would be more what yopu want. By adding *lpKernelTime and *lpUserTime spent between two consecutive calls, you'll get the effective CPU time used for that process, e.g.
#define FT2INT64(x) (*(( _int64*)&x))
 

FILETIME ftKernel1, ftKernel2;

FILETIME ftUser1, ftUser2;

FILETIME ftCreate, ftExit;
 

GetProcessTimes(&ftCreation,&ftExit,&ftKernel1,&ftUser1);
 

// run your exponential function here
 

GetProcessTimes(&ftCreation,&ftExit,&ftKernel2,&ftUser2);
 

__int64 lnTimeSpentUser = FT2INT64(ftUser2) - FT2INT64(ftUser1);

__int64 lnTimeSpentKernel = FT2INT64(ftKernel2) - FT2INT64(ftKernel1);
 

__int64 lnTimeSpentTotal = lnTimeSpentUser + lnTimeSpentKernel;
 

// result is in nanoseconds, see http://msdn.microsoft.com/en-us/library/ms724284(VS.85).aspx

Open in new window

0
 
LVL 8

Expert Comment

by:JIEXA
ID: 24526361
jkr,
'clock()' is told to measure CPU time, this is what is written in manuals. Is this wrong for Windows???
0
 
LVL 3

Expert Comment

by:Akumas
ID: 24560735
well,I had the same requirement to test my public lib's performance
here's my solution,just pseudocode, hope helpfull
it's really hard to remember exactly code:)

//class to statistic
class statistic
{
 static void record(const string& func_name, const long& elased_tickets)
  {
    //record and statistic cpu time for each function
  }
}

//class to record time
class caculator
{
  long begin_time;
  string name;
  caculator(const string& func_name)
  {
    name = func_name;
    begin_time = getTicketCount();
  }
  ~caculator()
  {
    long elapsed = getTicketCount() - begin_time;
    //record&statistic
    statistic::record(name, elapsed);
  }
}

usage:
void my_method1(xxx)
{
  caculator m("method1");
  //do somthing
}
void my_method2(xxx)
{
  caculator m("method2");
  //do somthing
}

you can measure different functions at same time, I like this very much:)

remember,getTicketCount is not fully reliable,it will reset after time,you should protect this situation or try other system function.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 8

Expert Comment

by:adg080898
ID: 24571018
To measure cpu time in Win32, use GetThreadTimes.

http://msdn.microsoft.com/en-us/library/ms683237.aspx

It returns the amount of user mode cpu time, kernel mode cpu time, thread creation time, and thread exit time...

FILETIME is simply a 64 bit value where 1 = 100 nanoseconds. 10000 = 1 millisecond. However, FILETIME is a (silly) structure that contains two 32-bit values that make up a 64 bit value.

I have used a union to allow you to nicely read the whole 64 bit value.


#include <windows.h>

#include <tchar.h>

#include <math.h>
 

union WrapFiletime

{

    FILETIME ft;

    __int64 value;

};
 

volatile double dummy;

void DoSomething()

{

    for (int i = 0; i < 200000000; ++i)

    {

        dummy = sqrt((double)i);

    }

}
 

void TimeSomething()

{

    WrapFiletime creationTime;

    WrapFiletime exitTime;

    WrapFiletime kernelTime;

    WrapFiletime userTime;

    GetThreadTimes(GetCurrentThread(), 

            &creationTime.ft, &exitTime.ft, 

            &kernelTime.ft, &userTime.ft);
 

    __int64 startKernelTime = kernelTime.value;

    __int64 startUserTime = userTime.value;
 

    // ..... DO SOMETHING .....

    DoSomething();

    // ..... DO SOMETHING .....
 

    GetThreadTimes(GetCurrentThread(), 

            &creationTime.ft, &exitTime.ft, 

            &kernelTime.ft, &userTime.ft);
 

    __int64 endKernelTime = kernelTime.value;

    __int64 endUserTime = userTime.value;
 

    _tprintf(_T("CPU time: kernel=%dms, user=%dms\n"),

            (int)((endKernelTime-startKernelTime)/10000),

            (int)((endUserTime-startUserTime)/10000));

}
 

int _tmain(int argc, _TCHAR* argv[])

{

    TimeSomething();

    return 0;

}

Open in new window

0
 
LVL 8

Expert Comment

by:adg080898
ID: 24571063
Devoney:
there is an intrinsic function __rdtsc() that always works on x86 (even on 64bit platform). But that doesn't answer his question, he wanted to factor out I/O time and time taken by other running programs, and just measure the cpu time consumed by his exponential function.

jkr:
just noticed the GetProcessTimes respose :) That is similar to my response, but it measures the time taken by all threads in the process. Mostly equivalent in a single thread scenario, assuming none if his libraries are creating worker threads and he's not using the system thread pool, etc.
0
 
LVL 8

Expert Comment

by:adg080898
ID: 27972628
I don't see why jkr's answer deserves 100% of the points. I posted a complete, runnable example that measures the time consumed in a thread, not the entire process.
0
 
LVL 86

Expert Comment

by:jkr
ID: 28022891
Um:

- I don't see that more than one thread was involved in that Q.
- you posted two weeks(!) later, where that question was already close to abandoned. I doubt that this was the intention of the asker - to wait for two weeks... "just noticed the GetProcessTimes respose" indicates that you're not really reading threads before posting, which is not something that is customary at this site... especially since you had a whopping two weeks to do so.
0
 
LVL 8

Expert Comment

by:adg080898
ID: 28474612
I don't need to be disrespected for donating time to a commercial site. I'm not sure why I'm wasting my time posting responses in here anyway.
0
 
LVL 8

Expert Comment

by:JIEXA
ID: 28972269
The first sentence of the accepted solution is wrong.
0
 
LVL 69

Expert Comment

by:Callandor
ID: 29034856
Yes, the last comment in the link I posted says "clock() doesn't necessarily have anything to do with time as measured by the clock on the wall -- it measures the time used by your process."
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Introduction: When experiencing some peculiar problem with the functioning of your PC, how many times has it happened that you look for a solution and even google can’t help? It could be that you are one of the only few people on earth who ma…
Great sound, comfort and fit, excellent build quality, versatility, compatibility. These are just some of the many reasons for choosing a headset from Sennheiser.
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now