[Linux] Différence d'informations temporelles en fonction de l'ID d'horloge de la fonction clock_gettime ()

J'ai vérifié la fonction clock_gettime () utilisée pour obtenir l'heure actuelle et mesurer le temps de traitement dans l'environnement Linux, donc je l'ai résumé.

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

Vous pouvez obtenir les informations d'heure en fonction du type d'horloge spécifié dans clk_id. Extraits des principaux types d'horloge.

Exemple de code

Créez un code source pour voir à quelle heure les informations sont réellement produites pour chacun. Le code source et l'exemple d'exécution sont présentés ci-dessous.

Lorsque le traitement est effectué en multi-thread, chaque heure de début de traitement, heure de fin de traitement et leur temps écoulé (différence) sont confirmés.

#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;
//----------------------------------------------------------
//Lié au temps
//----------------------------------------------------------
//fonction de calcul de différence de temps
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;
	}
}
//Classe de journal de temps
class TimeLog
{
private:
	struct timespec real;
	struct timespec mono;
	struct timespec boot;
	struct timespec pcpu;
	struct timespec tcpu;
public:
	//Obtenir l'heure actuelle
	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;
	}
	//Réglage du temps écoulé
	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;
	}
	//Sortie de journal
	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;

//Traitement ordinaire
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);
}

//Traitement lourd
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);
}

//Le traitement réel est léger uniquement avec 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);
}

//----------------------------------------------------------
//Traitement principal
//----------------------------------------------------------
int main(void)
{
	//Début de la mesure du fil principal
	TimeLog main_start = TimeLog().getTime().printLog("Main START");

	//Début du fil
	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);

	//En attente de la fin du fil
	pthread_join(tids[0], NULL);
	pthread_join(tids[1], NULL);
	pthread_join(tids[2], NULL);

	//Fin de la mesure du filetage principal
	TimeLog main_end = TimeLog().getTime().printLog("Main  END ");
	elapsed_main.setElapsedTime(main_start, main_end);

	//Afficher le journal
	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;
}

Exemple d'exécution

4 noyaux

      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

Pour CLOCK_REALTIME (réel), l'heure de l'époque Unix est donnée. CLOCK_THREAD_CPUTIME_ID (tcpu) est le temps CPU consommé par le thread correspondant, donc le temps écoulé de Thread_C, qui ne fait que dormir, est presque 0. Puisque CLOCK_PROCESS_CPUTIME_ID (pcpu) est le temps CPU consommé par tous les threads, Main est proche de la somme du temps CPU du thread Thread_A`` 7,957 et du temps CPU du thread Thread_B`` 15,932. Je suis.

Source de référence, 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] Différence d'informations temporelles en fonction de l'ID d'horloge de la fonction clock_gettime ()
Différence de résultats en fonction de l'argument du multiprocessus.
Créez un environnement Selenium sur Amazon Linux 2 dans les plus brefs délais
Sous Linux, l'horodatage d'un fichier est un peu dépassé.
Une fonction qui mesure le temps de traitement d'une méthode en python
Différence de vitesse d'exécution en fonction de la façon d'écrire la fonction Cython
[Comprendre en 3 minutes] Le début de Linux
Modifions automatiquement la palette de couleurs d'iTerm2 en fonction de l'heure de la journée
J'ai essayé de mesurer le temps d'attente de la file d'attente d'exécution d'un processus sous Linux
Différence de sortie de la fonction de fenêtre de longueur paire
En Python, changez le comportement de la méthode en fonction de la façon dont elle est appelée
Définir la limite supérieure du nombre de répétitions de fonctions récursives en Python
Récupérer l'appelant d'une fonction en Python
[2020July] Vérifiez l'UDID de l'iPad sous Linux
Lire la sortie du sous-processus, ouvrir en temps réel
Correction des arguments de la fonction utilisée dans map
Au moment de la mise à jour de python avec ubuntu
rsync Le comportement change en fonction de la présence ou de l'absence de la barre oblique de la source de copie
L'histoire de la création de l'environnement Linux le plus rapide au monde
Dessinez sur Jupyter en utilisant la fonction de tracé des pandas
Annonce de la disponibilité de Java 11 LTS sur Amazon Linux 2
Mettez la dernière version de Python dans Linux (Debian) du Chromebook
Remarque sur le comportement par défaut de collate_fn dans PyTorch
Enquête sur l'utilisation du machine learning dans les services réels
Exécutons la commande à temps avec le bot discord
Comportement à la fin de Linux moins en fonction de la source de connexion
[Jinja2] Changement de saut de ligne en fonction de la position du trait d'union
Avoir le graphique d'équation de la fonction linéaire dessiné en Python
Comptez le nombre de caractères dans le texte dans le presse-papiers sur Mac
Résumé des points d'achoppement à Django pour la première fois
Obtenez la date et l'heure actuelles en Python, en tenant compte du décalage horaire
Rendre la fonction de dessin de polices japonaises dans OpenCV en général
Définir des informations telles que la longueur sur le bord de NetworkX
Installez la dernière version de Git sur votre serveur Linux
Obtenez le nom d'hôte du PC hôte avec Docker sous Linux
Précautions lors de la superposition de la fonction de densité de probabilité et de l'histogramme dans matplotlib
Rendement dans la classe qui a hérité de l'unittest.TestCase ne fonctionnait pas avec le nez (selon la version du nez?)
Comment résoudre le problème qui se passe mal à chaque fois que vous mettez sous tension Linux