[Linux] Difference in time information depending on the clock ID of the clock_gettime () function

I checked the clock_gettime () function used to get the current time and measure the processing time in the Linux environment, so I summarized it.

clock_gettime () function

#include <time.h>

int clock_gettime(clockid_t clk_id, struct timespec *tp);

struct timespec {
        __kernel_time_t tv_sec;                 /* seconds */
        long            tv_nsec;                /* nanoseconds */
};

You can get the time information according to the clock type specified in clk_id. Excerpts from the main clock types.

Sample code

Create the source code of what kind of time information is actually output for each. The source code and execution example are shown below.

When processing is performed in multithread, each processing start time, processing end time, and their elapsed time (difference) are confirmed.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/times.h>

static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
//----------------------------------------------------------
//Time related
//----------------------------------------------------------
//timespec difference calculation function
inline void sub_timespec(struct timespec* res, const struct timespec* a, const struct timespec* b)
{
	if (a->tv_nsec >= b->tv_nsec) {
		res->tv_nsec = a->tv_nsec - b->tv_nsec;
		res->tv_sec = a->tv_sec - b->tv_sec;
	} else {
		res->tv_nsec = 1000000000 + a->tv_nsec - b->tv_nsec;
		res->tv_sec = a->tv_sec - b->tv_sec - 1;
	}
}
//Time log class
class TimeLog
{
private:
	struct timespec real;
	struct timespec mono;
	struct timespec boot;
	struct timespec pcpu;
	struct timespec tcpu;
public:
	//Get the current time
	TimeLog& getTime() {
		clock_gettime(CLOCK_REALTIME, &real);
		clock_gettime(CLOCK_MONOTONIC, &mono);
		clock_gettime(CLOCK_BOOTTIME , &boot);
		clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &pcpu);
		clock_gettime(CLOCK_THREAD_CPUTIME_ID , &tcpu);
		return *this;
	}
	//Elapsed time setting
	TimeLog& setElapsedTime(const TimeLog& start, const TimeLog& end) {
		sub_timespec(&real, &end.real, &start.real);
		sub_timespec(&mono, &end.mono, &start.mono);
		sub_timespec(&boot, &end.boot, &start.boot);
		sub_timespec(&pcpu, &end.pcpu, &start.pcpu);
		sub_timespec(&tcpu, &end.tcpu, &start.tcpu);
		return *this;
	}
	//Log output
	TimeLog& printLog(const char* label) {
		pthread_mutex_lock(&g_mutex);
		printf("%16s", label);
		printf(": real=%ld.%09ld", real.tv_sec, real.tv_nsec);
		printf(", mono=%ld.%09ld", mono.tv_sec, mono.tv_nsec);
		printf(", boot=%ld.%09ld", boot.tv_sec, boot.tv_nsec);
		printf(", pcpu=%ld.%09ld", pcpu.tv_sec, pcpu.tv_nsec);
		printf(", tcpu=%ld.%09ld", tcpu.tv_sec, tcpu.tv_nsec);
		printf("\n");
		pthread_mutex_unlock(&g_mutex);
		return *this;
	}
};

//----------------------------------------------------------
TimeLog  elapsed_main;
TimeLog  elapsed_A;
TimeLog  elapsed_B;
TimeLog  elapsed_C;

//Ordinary processing
void* thread_A(void* param)
{
	TimeLog start = TimeLog().getTime().printLog("Thread_A START");
	for (int64_t ans = 0, i = 0; i <= 1000000000; i++) ans += i;
	TimeLog end = TimeLog().getTime().printLog("Thread_A  END ");
	elapsed_A.setElapsedTime(start, end);
}

//Heavy processing
void* thread_B(void* param)
{
	TimeLog start = TimeLog().getTime().printLog("Thread_B START");
	for (int64_t ans = 0, i = 0; i <= 2000000000; i++) ans += i;
	TimeLog end = TimeLog().getTime().printLog("Thread_B  END ");
	elapsed_B.setElapsedTime(start, end);
}

//Actual processing is light only with Sleep
void* thread_C(void* param)
{
	TimeLog start = TimeLog().getTime().printLog("Thread_C START");
	sleep(5);
	TimeLog end = TimeLog().getTime().printLog("Thread_C  END ");
	elapsed_C.setElapsedTime(start, end);
}

//----------------------------------------------------------
//Main processing
//----------------------------------------------------------
int main(void)
{
	//Main thread measurement started
	TimeLog main_start = TimeLog().getTime().printLog("Main START");

	//Thread start
	pthread_t tids[3];
	pthread_create(&tids[0], NULL, thread_A, NULL);
	pthread_create(&tids[1], NULL, thread_B, NULL);
	pthread_create(&tids[2], NULL, thread_C, NULL);

	//Waiting for thread to end
	pthread_join(tids[0], NULL);
	pthread_join(tids[1], NULL);
	pthread_join(tids[2], NULL);

	//End of main thread measurement
	TimeLog main_end = TimeLog().getTime().printLog("Main  END ");
	elapsed_main.setElapsedTime(main_start, main_end);

	//View log
	printf("\nElapsed Time:\n");
	elapsed_main.printLog("Main");
	elapsed_A.printLog("Thread_A");
	elapsed_B.printLog("Thread_B");
	elapsed_C.printLog("Thread_C");
	return 0;
}

Execution example

4 cores

      Main START: real=1575812537.439121016, mono=32063.696304893, boot=32063.696308226, pcpu=0.004150000, tcpu=0.004155886
  Thread_A START: real=1575812537.439749506, mono=32063.696932913, boot=32063.696936038, pcpu=0.004697188, tcpu=0.000063125
  Thread_B START: real=1575812537.439850391, mono=32063.697033799, boot=32063.697034945, pcpu=0.004892084, tcpu=0.000040885
  Thread_C START: real=1575812537.440102943, mono=32063.697286351, boot=32063.697287705, pcpu=0.005163542, tcpu=0.000039270
  Thread_C  END : real=1575812542.440262790, mono=32068.697446093, boot=32068.697448385, pcpu=9.990084615, tcpu=0.000146666
  Thread_A  END : real=1575812545.398370708, mono=32071.655553959, boot=32071.655556043, pcpu=15.896352351, tcpu=7.957370441
  Thread_B  END : real=1575812553.410668627, mono=32079.667851930, boot=32079.667854222, pcpu=23.895293170, tcpu=15.932487989
      Main  END : real=1575812553.410906544, mono=32079.668089847, boot=32079.668092139, pcpu=23.895542597, tcpu=0.005018229

Elapsed Time:
            Main: real=15.971785528, mono=15.971784954, boot=15.971783913, pcpu=23.891392597, tcpu=0.000862343
        Thread_A: real=7.958621202, mono=7.958621046, boot=7.958620005, pcpu=15.891655163, tcpu=7.957307316
        Thread_B: real=15.970818236, mono=15.970818131, boot=15.970819277, pcpu=23.890401086, tcpu=15.932447104
        Thread_C: real=5.000159847, mono=5.000159742, boot=5.000160680, pcpu=9.984921073, tcpu=0.000107396

Unix Epoch Time is given for CLOCK_REALTIME (real). CLOCK_THREAD_CPUTIME_ID (tcpu) is the CPU time consumed by the corresponding thread, so the elapsed time of Thread_C, which is only sleeping, is almost 0. Since CLOCK_PROCESS_CPUTIME_ID (pcpu) is the CPU time consumed by all threads, Main is close to the sum of Thread_A thread CPU time 7.957 and Thread_B thread CPU time 15.932. I am.

Reference source etc.

https://www.mm2d.net/main/prog/c/time-05.html https://linuxjm.osdn.jp/html/LDP_man-pages/man2/clock_gettime.2.html

Recommended Posts

[Linux] Difference in time information depending on the clock ID of the clock_gettime () function
Difference in results depending on the argument of multiprocess.Process
Build a Selenium environment on Amazon Linux 2 in the shortest time
On Linux, the time stamp of a file is a little past.
A function that measures the processing time of a method in python
Difference in execution speed depending on how to write Cython function
[Understanding in 3 minutes] The beginning of Linux
Let's change the color scheme of iTerm2 automatically depending on the time zone
I measured the run queue wait time of a process on Linux
Difference in output of even-length window function
In Python, change the behavior of the method depending on how it is called
Set an upper limit on the number of recursive function iterations in Python
Get the caller of a function in Python
[2020July] Check the UDID of the iPad on Linux
Read the output of subprocess.Popen in real time
Fix the argument of the function used in map
At the time of python update on ubuntu
rsync Behavior changes depending on the presence or absence of the slash in the copy source
The story of building the fastest Linux environment in the world
Drawing on Jupyter using the plot function of pandas
Announcing the availability of Java 11 LTS on Amazon Linux 2
Put the latest version of Python on linux (Debian) on Chromebook
A note on the default behavior of collate_fn in PyTorch
Survey on the use of machine learning in real services
Let's execute the command on time with the bot of discord
Behavior when Linux less ends depending on the connection source
Analyzing data on the number of corona patients in Japan
[Jinja2] Changes in line breaks depending on the hyphen position
Have the equation graph of the linear function drawn in Python
Count the number of characters in the text on the clipboard on mac
Summary of stumbling blocks in Django for the first time
Get the current date and time in Python, considering the time difference
Make the function of drawing Japanese fonts in OpenCV general
Set information such as length on the edge of NetworkX
Install the latest version of Git on your Linux server
Get the host name of the host PC with Docker on Linux
Precautions when drawing the probability density function and the histogram on top of each other in matplotlib
Yield in a class that inherits unittest.TestCase didn't work with nose (depending on the version of nose?)
How to solve the problem that time goes wrong every time you turn on the power in Linux