[Linux] Unterschied in den Zeitinformationen in Abhängigkeit von der Uhr-ID der Funktion clock_gettime ()

Ich habe die Funktion clock_gettime () überprüft, um die aktuelle Zeit abzurufen und die Verarbeitungszeit in der Linux-Umgebung zu messen, und habe sie zusammengefasst.

Funktion clock_gettime ()

#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 */
};

Sie können die Zeitinformationen gemäß dem in clk_id angegebenen Uhrentyp abrufen. Auszüge aus den Hauptuhrentypen.

Beispielcode

Erstellen Sie einen Quellcode, um zu sehen, welche Zeitinformationen tatsächlich für jeden ausgegeben werden. Der Quellcode und das Ausführungsbeispiel sind unten dargestellt.

Wenn die Verarbeitung in einem Multithread ausgeführt wird, werden jede Verarbeitungsstartzeit, Verarbeitungsendzeit und ihre verstrichene Zeit (Differenz) bestätigt.

#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;
//----------------------------------------------------------
//Zeitbezogen
//----------------------------------------------------------
//Zeitspezifikationsdifferenzberechnungsfunktion
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;
	}
}
//Zeitprotokollklasse
class TimeLog
{
private:
	struct timespec real;
	struct timespec mono;
	struct timespec boot;
	struct timespec pcpu;
	struct timespec tcpu;
public:
	//Aktuelle Zeit abrufen
	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;
	}
	//Einstellung der verstrichenen Zeit
	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;
	}
	//Protokollausgabe
	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;

//Ordentliche Verarbeitung
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);
}

//Schwere Verarbeitung
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);
}

//Die tatsächliche Verarbeitung ist nur im Ruhezustand leicht
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);
}

//----------------------------------------------------------
//Hauptverarbeitung
//----------------------------------------------------------
int main(void)
{
	//Start der Hauptgewindemessung
	TimeLog main_start = TimeLog().getTime().printLog("Main START");

	//Fadenstart
	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);

	//Warten auf das Ende des Threads
	pthread_join(tids[0], NULL);
	pthread_join(tids[1], NULL);
	pthread_join(tids[2], NULL);

	//Ende der Hauptgewindemessung
	TimeLog main_end = TimeLog().getTime().printLog("Main  END ");
	elapsed_main.setElapsedTime(main_start, main_end);

	//Protokoll anzeigen
	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;
}

Ausführungsbeispiel

4 Kerne

      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

Für CLOCK_REALTIME (real) wird die Unix-Epochenzeit angegeben. CLOCK_THREAD_CPUTIME_ID (tcpu) ist die vom entsprechenden Thread verbrauchte CPU-Zeit, sodass die verstrichene Zeit von Thread_C, die nur schläft, fast 0 beträgt. Da "CLOCK_PROCESS_CPUTIME_ID" (pcpu) die von allen Threads verbrauchte CPU-Zeit ist, liegt "Main" nahe an der Summe der Thread-CPU-Zeit von "Thread_A" 7.957 "und der Thread-CPU-Zeit" 15.932 "von" Thread_B ". Ich bin.

Referenzquelle usw.

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] Unterschied in den Zeitinformationen in Abhängigkeit von der Uhr-ID der Funktion clock_gettime ()
Unterschied in den Ergebnissen abhängig vom Argument von multiprocess.Process
Erstellen Sie in kürzester Zeit eine Selenium-Umgebung unter Amazon Linux 2
Unter Linux ist der Zeitstempel einer Datei etwas vorbei.
Eine Funktion, die die Verarbeitungszeit einer Methode in Python misst
Unterschied in der Ausführungsgeschwindigkeit abhängig vom Schreiben der Cython-Funktion
[Verständnis in 3 Minuten] Der Beginn von Linux
Lassen Sie uns das Farbschema von iTerm2 je nach Tageszeit automatisch ändern
Ich habe versucht, die Wartezeit der Ausführungswarteschlange eines Prozesses unter Linux zu messen
Unterschied in der Ausgabe der Fensterfunktion mit gerader Länge
Ändern Sie in Python das Verhalten der Methode je nach Aufruf
Legen Sie die Obergrenze für die Anzahl der Wiederholungen rekursiver Funktionen in Python fest
Holen Sie sich den Aufrufer einer Funktion in Python
[2020Juli] Überprüfen Sie die UDID des iPad unter Linux
Lesen Sie die Ausgabe von subprocess.Popen in Echtzeit
Korrigieren Sie die Argumente der in map verwendeten Funktion
Zum Zeitpunkt des Python-Updates mit Ubuntu
rsync Das Verhalten ändert sich abhängig vom Vorhandensein oder Fehlen des Schrägstrichs der Kopierquelle
Die Geschichte des Aufbaus der schnellsten Linux-Umgebung der Welt
Zeichnen auf Jupyter mit der Plot-Funktion von Pandas
Ankündigung der Verfügbarkeit von Java 11 LTS unter Amazon Linux 2
Stellen Sie die neueste Version von Python in Linux (Debian) von Chromebook
Hinweis zum Standardverhalten von collate_fn in PyTorch
Umfrage zum Einsatz von maschinellem Lernen in realen Diensten
Lassen Sie uns den Befehl pünktlich mit dem Bot der Zwietracht ausführen
Verhalten am Ende von Linux weniger abhängig von der Verbindungsquelle
[Jinja2] Änderung des Zeilenumbruchs abhängig von der Position des Bindestrichs
Lassen Sie das Gleichungsdiagramm der linearen Funktion in Python zeichnen
Zählen Sie die Anzahl der Zeichen im Text in der Zwischenablage auf dem Mac
Zusammenfassung der Stolperpunkte in Django zum ersten Mal
Holen Sie sich das aktuelle Datum und die aktuelle Uhrzeit in Python unter Berücksichtigung des Zeitunterschieds
Machen Sie die Funktion zum Zeichnen japanischer Schriftarten in OpenCV allgemein
Legen Sie Informationen wie die Länge am Rand von NetworkX fest
Installieren Sie die neueste Version von Git auf Ihrem Linux-Server
Rufen Sie den Hostnamen des Host-PCs mit Docker unter Linux ab
Vorsichtsmaßnahmen bei der Überlagerung der Wahrscheinlichkeitsdichtefunktion und des Histogramms in matplotlib
Ausbeute in einer Klasse, die unittest geerbt hat. TestCase funktionierte nicht mit der Nase (abhängig von der Version der Nase?)
So lösen Sie das Problem, dass die Zeit jedes Mal schief geht, wenn Sie die Stromversorgung unter Linux einschalten