How to measure execution time of a function? - c++

I've searched SO and found relevant questions answered but I'm confused about the three different clock definitions. Considering I compile with Mingw on Windows;
I wonder whether the code below is OK or not? (I do not really need nanoseconds or microseconds precision; just testing...)
Which one should I use?
std::chrono::high_resolution_clock
std::chrono::system_clock
std::chrono::steady_clock
#include <iostream>
#include <chrono>
...
...
...
void printTimeElapsed(
std::chrono::high_resolution_clock::time_point t0,
std::chrono::high_resolution_clock::time_point t1)
{
int64_t hh; // hour
int64_t mm; // min
int64_t ss; // sec
int64_t ml; // millisec
int64_t mc; // microsec
int64_t ns; // nanosec
ns = std::chrono::duration_cast<std::chrono::nanoseconds>(t1 - t0).count();
std::cout << ns << std::endl;
mc = ns / 1000;
ns %= 1000;
ml = mc / 1000;
mc %= 1000;
ss = ml / 1000;
ml %= 1000;
mm = ss / 60;
ss %= 60;
hh = mm / 60;
mm %= 60;
std::cout
<< std::setfill('0') << std::setw(3) << hh << ":"
<< std::setfill('0') << std::setw(2) << mm << ":"
<< std::setfill('0') << std::setw(2) << ss << "."
<< std::setfill('0') << std::setw(3) << ml << "."
<< std::setfill('0') << std::setw(3) << mc << "."
<< std::setfill('0') << std::setw(3) << ns << std::endl;
return;
}
...
...
...
int main(
int argc,
char *argv[])
{
std::chrono::high_resolution_clock::time_point t0;
std::chrono::high_resolution_clock::time_point t1;
...
...
t0 = std::chrono::high_resolution_clock::now();
/* call the function to be measured */
t1 = std::chrono::high_resolution_clock::now();
printTimeElapsed(t0, t1);
...
...
return (0);
}

system_clock is not steady: is subject to time adjustments.
high_resolution_clock is not guaranteed to be steady.
It means for users to use steady_clock for measurement, and because of this, implementers need to make the steady_clock of a high resolution.
Windows implementation of steady_clock should be based on QueryPerformanceCounter / QueryPerformanceFrequency, which is highest resolution of available API. This is true for MSVC, need to check for MinGW.

Related

How people used to measure time before chrono?

Since C++11 we can measure time as in https://en.cppreference.com/w/cpp/chrono
#include <iostream>
#include <chrono>
long fibonacci(unsigned n)
{
if (n < 2) return n;
return fibonacci(n-1) + fibonacci(n-2);
}
int main()
{
auto start = std::chrono::steady_clock::now();
std::cout << "f(42) = " << fibonacci(42) << '\n';
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;
std::cout << "elapsed time: " << elapsed_seconds.count() << "s\n";
}
How people used to measure time before chrono? Was there a C++ way to do it or people used to reply on OS specific facilities?

Correct way to get Windows CPU utilization for multiprocessor

What I want to achieve is I can get every CPUs utilization (I have 4 CPU core, so I expect I can get all of them like in resmon.exe) and the sum of them (Like in the TaskManager.exe)
I have read on some soure on how I can get the processors utilization is by doing some math on the CPU time. I tried to use NtQuerySystemInformation to get the necessary data.
#include <windows.h>
#include <vector>
#include <iostream>
#include <winternl.h>
#pragma comment(lib, "Ntdll.lib")
typedef struct
_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R {
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER DpcTime;
LARGE_INTEGER InterruptTime;
ULONG InterruptCount;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R;
static long long toInteger(LARGE_INTEGER const & integer)
{
#ifdef INT64_MAX // Does the compiler natively support 64-bit integers?
return integer.QuadPart;
#else
return (static_cast<long long>(integer.HighPart) << 32) | integer.LowPart;
#endif
}
class CPU
{
public:
uint64_t prev_idle = 0;
uint64_t prev_ker = 0;
uint64_t prev_user = 0;
uint64_t cur_idle = 0;
uint64_t cur_ker = 0;
uint64_t cur_user = 0;
double get()
{
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R *a = new SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R[4];
// 4 is the total of CPU (4 cores)
NtQuerySystemInformation(SystemProcessorPerformanceInformation, a, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R) * 4, NULL);
prev_idle = cur_idle;
prev_ker = cur_ker;
prev_user = cur_user;
cur_idle = 0;
cur_ker = 0;
cur_user = 0;
// 4 is the total of CPU (4 cores)
// Sum up the SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R array so I can get the utilization from all of the CPU
for (int i = 0; i < 4; ++i)
{
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R b = a[i];
cur_idle += toInteger(b.IdleTime);
cur_ker += toInteger(b.KernelTime);
cur_user += toInteger(b.UserTime);
}
std::cout << "Cur idle " << cur_idle << '\n';
std::cout << "Cur ker " << cur_ker << '\n';
std::cout << "Cur user " << cur_user << '\n';
uint64_t delta_idle = cur_idle - prev_idle;
uint64_t delta_kernel = cur_ker - prev_ker;
uint64_t delta_user = cur_user - prev_user;
std::cout << "Delta idle " << delta_idle << '\n';
std::cout << "Delta ker " << delta_kernel << '\n';
std::cout << "Delta user " << delta_user << '\n';
uint64_t total_sys = delta_kernel + delta_user;
uint64_t kernel_total = delta_kernel - delta_idle;
delete[] a;
// return (total_sys - delta_idle) * 100.0 / total_sys;
return (kernel_total + delta_user) * 100.0 / total_sys;
}
};
int main()
{
CPU a;
std::cout << "starting" << '\n';
while(1)
{
std::cout << a.get() << '\n';
Sleep(1000);
}
return 0;
}
And to get the individual CPU utilization, I don't have to sum all of the CPUs, just choose one of the SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R array element.
My question is
Am I doing it right? Because when I check my program with the CPU utilization in the TaskManager.exe, it somewhat different.
Is there any better approach other than using NtQuerySystemInformation (Because Microsoft has mention "NtQuerySystemInformation may be altered or unavailable in future versions of Windows. Applications should use the alternate functions listed in this topic.")?

how to execute the running time of a program written in c++?

I have code that generates random numbers from 1-100 and sorts them using the merge sort which I already have in a separate function. Everything works but when I implement clock(); to try and get the running time, I always get zero. I have even tried with larger numbers like 10000 but still, the time passed always gives me zero. here is my code
int main() {
clock_t startTime;
clock_t endTime;
clock_t timePassed;
int array[100];
srand(time(NULL));
int n = sizeof(array) / sizeof(array[0]);
startTime = clock();
for (int j = 0; j < 100; j++)
{
array[j] = rand() % 100+1;
std::cout << array[j] << " ";
}
std::cout << "\n";
MergeSort(array, n);
std::cout << "After Merge Sort :" << std::endl;
PrintArray(array, n);
endTime = clock();
timePassed = ((endTime - startTime) / CLOCKS_PER_SEC);
std::cout << "\n" << timePassed;
}
return 0;
}
use
double timePassed = (endTime - startTime) / static_cast<double>(CLOCKS_PER_SEC);
Plan B for higher accuracy:
#include <iostream>
#include <chrono>
// ...
auto start_time{ std::chrono::high_resolution_clock::now() };
// ... code you want to time
auto end_time{ std::chrono::high_resolution_clock::now() };
std::cout << std::chrono::duration_cast<std::chrono::seconds>(end_time - start_time).count() << ":";
std::cout << std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time).count() << ":";
// ...
If you are developing on a Unix system and want to measure the execution time from an application, you can also use the 'time' command like:
time myapplication
see
time (Unix) - Wikipedia

Converting chrono::duration type to std::tm type

I am writing a program that takes input a date from the user, uses it to initialize a tm struct, then using chrono::time_points performs some chrono::duration operation, such as getting the age.
Here is my code:
#include <iostream>
#include <chrono>
#include <ctime>
#include <iomanip>
using namespace std;
int main(){
//representing a date
tm *birthday = new tm{00, 30, 00, 07, 11, 97};
//convert to time t
time_t bt = mktime(birthday);
//convert time_t to time_point
chrono::system_clock::time_point t = chrono::system_clock::from_time_t(bt);
chrono::system_clock::time_point now = chrono::system_clock::now();
/*.. Testing
time_t nn = chrono::system_clock::to_time_t(now);
time_t tnn = chrono::system_clock::to_time_t(t);
*/
chrono::system_clock::duration lft = now - t;
//convert to timepoint
chrono::system_clock::time_point tlft{lft};
time_t lifetime = chrono::system_clock::to_time_t(tlft);
cout << put_time(localtime(&lifetime), "%F %T") << endl;
return 0;
}
And my output is something like this:
$> 1990-02-10 09:42:46
So, according to my understanding, it performs a plain mathematical subtraction on the ticks and using localtime, converts it to a date since EPOCH that is why it is giving me 1990. I want to know, is there any way, to convert the duration straight into struct tm, so that I should get something like 20 years?
Here is how you extract a duration in the unit of your choice:
std::chrono::duration<double> lft = now - t;
using year = std::chrono::duration<int, std::ratio<31557600>>;
auto nby = std::chrono::duration_cast<year>(lft);
std::cout << nby.count() << "\n";
With this in mind, I'll suggest an implementation of the taste of:
struct Age
{
using year = std::chrono::duration<int, std::ratio<31'557'600>>;
using month = std::chrono::duration<int, std::ratio< 2'592'000>>;
using day = std::chrono::duration<int, std::ratio< 86'400>>;
using hour = std::chrono::hours;
using minute = std::chrono::minutes;
using second = std::chrono::seconds;
Age(std::chrono::system_clock::time_point birth)
: _age(std::chrono::system_clock::now() - birth)
{}
template<class Duration>
auto extract()
{
const auto result = std::chrono::duration_cast<Duration>(_age);
_age -= result;
return result;
}
friend std::ostream& operator<<(std::ostream& os, Age age)
{
const auto years = age.extract<year>();
const auto monthes = age.extract<month>();
const auto days = age.extract<day>();
const auto hours = age.extract<hour>();
const auto minutes = age.extract<minute>();
const auto seconds = age.extract<second>();
return os << years.count()
<< ":" << std::setw(2) << std::setfill('0') << monthes.count()
<< ":" << std::setw(2) << std::setfill('0') << days.count()
<< " " << std::setw(2) << std::setfill('0') << hours.count()
<< ":" << std::setw(2) << std::setfill('0') << minutes.count()
<< ":" << std::setw(2) << std::setfill('0') << seconds.count()
;
}
private:
std::chrono::duration<double> _age;
};
Prints 20:01:10 12:43:40 with your example date (live demo).

Outputting date in ISO 8601 format

How can I get a date in the following format in C++:
2016-04-26T19:50:48Z
#include <chrono>
#include <ctime>
time_t _tm = time(NULL);
struct tm*curtime = localtime(&_tm);
And outputting as asctime(curtime)
The current output is: "Thu Apr 28 16:02:41 2016\n"
Documentation is your friend:
std::time_t t
= std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
std::cout << std::put_time( std::localtime( &t ), "%FT%T%z" );
in my system yields
2016-04-29T02:48:56+0200
Based on #Uri's answer which fixes a few bugs and shows the time in the proper timezone along with the milliseconds in ISO8601 format:
auto now = std::chrono::system_clock::now();
std::time_t time = std::chrono::system_clock::to_time_t(now);
std::tm* now_tm = std::localtime(&time);
long long timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
std::cout << std::setfill('0')
<< std::put_time(now_tm, "%FT%H:%M:")
<< std::setw(2) << (timestamp / 1000) % 60 << '.'
<< std::setw(3) << timestamp % 1000
<< std::put_time(now_tm, "%z");
I'm combining the std::localtime which gives me calendar values, with std::chrono functions that gives me the precise methods. Here is my code:
#include <ctime>
#include <chrono>
...
auto now = std::chrono::system_clock::now();
auto now_c = std::chrono::system_clock::to_time_t(now)
auto now_tm = std::localtime(&now_c);
auto now_since_epoch = now.time_since_epoch(); // since 1970
auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now_since_epoch).count();
std::cout << std::setfill('0') <<
std::setw(4) << now_tm->tm_year + 1900 << '-' <<
std::setw(2) << now_tm->tm_mon + 1 << '-' <<
std::setw(2) << now_tm->tm_mday << 'T' <<
std::setw(2) << now_ms % (24*60*60*1000) << ':' <<
std::setw(2) << now_ms % (60*60*1000) << ':' <<
std::setw(2) << now_ms % (60*1000) << '.' <<
std::setw(3) << now_ms % (1000);
Although verbose, it is actually doing less than strftime.