C ++ obtenir millisecondes de temps sur Linux - horloge () ne semble pas fonctionner correctement

StackOverflow https://stackoverflow.com/questions/588307

  •  09-09-2019
  •  | 
  •  

Question

Sous Windows, clock() retourne le temps en millisecondes, mais sur cette case Linux sur lesquels je travaille, il arrondit au 1000 le plus proche si la précision est seulement au niveau « deuxième » et non au niveau des millisecondes.

J'ai trouvé une solution avec Qt en utilisant la classe QTime, instanciation d'un objet et d'appeler start() sur elle alors d'appeler elapsed() pour obtenir le nombre de millisecondes écoulées.

Je suis genre de chance parce que je travaille avec Qt pour commencer, mais je voudrais une solution qui ne repose pas sur les bibliothèques de tiers,

Yat-il pas moyen standard pour le faire?

UPDATE

S'il vous plaît ne recommande pas Boost ..

Si Boost et Qt peuvent le faire, il est sûrement pas de la magie, il doit y avoir quelque chose de standard qu'ils utilisent!

Était-ce utile?

La solution

Vous pouvez utiliser gettimeofday au début et à la fin de votre méthode, puis différence les deux struct de retour. Vous obtiendrez une structure comme suit:

struct timeval {
  time_t tv_sec;
  suseconds_t tv_usec;
}

Autres conseils

#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
    struct timeval start, end;

    long mtime, seconds, useconds;    

    gettimeofday(&start, NULL);
    usleep(2000);
    gettimeofday(&end, NULL);

    seconds  = end.tv_sec  - start.tv_sec;
    useconds = end.tv_usec - start.tv_usec;

    mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;

    printf("Elapsed time: %ld milliseconds\n", mtime);

    return 0;
}

S'il vous plaît noter que clock ne pas mesure du temps d'horloge murale. Cela signifie que si votre programme prend 5 secondes, clock ne mesure pas nécessairement 5 secondes, mais pourrait plus (votre programme pourrait exécuter plusieurs threads et pourrait donc consommer plus de CPU que le temps réel) ou moins. Il mesure une approximation de temps CPU utilisé. Pour voir la différence considérer ce code

#include <iostream>
#include <ctime>
#include <unistd.h>

int main() {
    std::clock_t a = std::clock();
    sleep(5); // sleep 5s
    std::clock_t b = std::clock();

    std::cout << "difference: " << (b - a) << std::endl;
    return 0;
}

Il produit sur mon système

$ difference: 0

Parce que tout ce que nous ne couchait et ne pas utiliser de temps CPU! Cependant, l'utilisation gettimeofday nous obtenons ce que nous voulons (?)

#include <iostream>
#include <ctime>
#include <unistd.h>
#include <sys/time.h>

int main() {
    timeval a;
    timeval b;

    gettimeofday(&a, 0);
    sleep(5); // sleep 5s
    gettimeofday(&b, 0);

    std::cout << "difference: " << (b.tv_sec - a.tv_sec) << std::endl;
    return 0;
}

Sorties sur mon système

$ difference: 5

Si vous avez besoin d'une plus grande précision mais que vous souhaitez obtenir temps CPU , alors vous pouvez envisager d'utiliser la fonction getrusage.

Je recommande également les outils proposés par Boost. Soit la minuterie Boost mentionné, ou pirater quelque chose de Boost.DateTime ou il y a nouvelle bibliothèque proposée dans le bac à sable - Boost.Chrono : Ce dernier sera un remplacement pour la minuterie et mettra en vedette:

  • temps de C ++ 0x bibliothèque standard, y compris les services publics:
    • Modèle de classe duration
    • Modèle de classe time_point
    • Horloges:
      • system_clock
      • monotonic_clock
      • high_resolution_clock
  • modèle de classe timer, avec typedefs:
    • system_timer
    • monotonic_timer
    • high_resolution_timer
  • horloges de processus et minuteries:
    • process_clock, la capture réelle, CPU utilisateur et système temps-CPU.
    • process_timer, la capture réelle écoulée, CPU utilisateur et système temps-CPU.
    • run_timer, rapports de pratique | process_timer | résultats.
  • La bibliothèque Standard C ++ 0x compilation arithmétique rationnelle.

est ici la source de la liste des fonctionnalités

J'ai écrit une classe Timer basée sur réponse CTT. Il peut être utilisé de la manière suivante:

Timer timer = Timer();
timer.start();
/* perform task */
double duration = timer.stop();
timer.printTime(duration);

Voici sa mise en œuvre:

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
using namespace std;

class Timer {
private:

    timeval startTime;

public:

    void start(){
        gettimeofday(&startTime, NULL);
    }

    double stop(){
        timeval endTime;
        long seconds, useconds;
        double duration;

        gettimeofday(&endTime, NULL);

        seconds  = endTime.tv_sec  - startTime.tv_sec;
        useconds = endTime.tv_usec - startTime.tv_usec;

        duration = seconds + useconds/1000000.0;

        return duration;
    }

    static void printTime(double duration){
        printf("%5.6f seconds\n", duration);
    }
};

Si vous n'avez pas besoin du code pour être portable vieux unix, vous pouvez utiliser clock_gettime (), qui vous donnera le temps dans nanosecondes (si votre processeur prend en charge cette résolution). Il est Posix, mais à partir de 2001.

horloge ()

a souvent une résolution assez moche. Si vous voulez mesurer le temps au niveau de la milliseconde, une alternative est d'utiliser clock_gettime (), comme expliqué dans cette question.

(Rappelez-vous que vous devez -lrt sous Linux).

Avec 11 C ++ et std::chrono::high_resolution_clock que vous pouvez faire ceci:

#include <iostream>
#include <chrono>
#include <thread>
typedef std::chrono::high_resolution_clock Clock;

int main()
{
    std::chrono::milliseconds three_milliseconds{3};

    auto t1 = Clock::now();
    std::this_thread::sleep_for(three_milliseconds);
    auto t2 = Clock::now();

    std::cout << "Delta t2-t1: " 
              << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count()
              << " milliseconds" << std::endl;
}

Sortie:

Delta t2-t1: 3 milliseconds

Lien vers démo: http://cpp.sh/2zdtu

Horloge () ne retourne pas millisecondes ou secondes sur linux. Habituellement retourne horloge () microsecondes sur un système Linux. La bonne façon d'interpréter la valeur retournée par l'horloge () est de le diviser par CLOCKS_PER_SEC pour savoir combien de temps a passé.

Cela devrait fonctionner ... testé sur un mac ...

#include <stdio.h>
#include <sys/time.h>

int main() {
        struct timeval tv;
        struct timezone tz;
        struct tm *tm;
        gettimeofday(&tv,&tz);
        tm=localtime(&tv.tv_sec);
        printf("StartTime: %d:%02d:%02d %d \n", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec);
}

Ouais ... courir deux fois et soustrayez ...

Dans le clock standard POSIX a sa valeur de retour définie en termes de symbole CLOCKS_PER_SEC et une mise en œuvre est libre de définir ce en aucune façon pratique. Sous Linux, j'ai eu bonne chance avec la fonction times().

gettimeofday - le problème est que la volonté peut avoir des valeurs plus basses si vous vous changez l'horloge matérielle (avec NTP par exemple) Boost - non disponible pour ce projet horloge () -. renvoie généralement un nombre entier de 4 octets, wich signifie que sa faible capacité, et après un certain temps, il renvoie les nombres négatifs

Je préfère créer ma propre classe et mettre à jour toutes les 10 millisecondes, donc cette façon est plus souple, et je peux même l'améliorer d'avoir des abonnés.

class MyAlarm {
static int64_t tiempo;
static bool running;
public:
static int64_t getTime() {return tiempo;};
static void callback( int sig){
    if(running){
        tiempo+=10L;
    }
}
static void run(){ running = true;}
};

int64_t MyAlarm::tiempo = 0L;
bool MyAlarm::running = false;

pour le rafraîchir J'utilise setitimer:

int main(){
struct sigaction sa; 
struct itimerval timer; 

MyAlarm::run();
memset (&sa, 0, sizeof (sa)); 
sa.sa_handler = &MyAlarm::callback; 

sigaction (SIGALRM, &sa, NULL); 


timer.it_value.tv_sec = 0; 
timer.it_value.tv_usec = 10000; 



timer.it_interval.tv_sec = 0; 
timer.it_interval.tv_usec = 10000; 


setitimer (ITIMER_REAL, &timer, NULL); 
.....

Regardez setitimer et ITIMER_VIRTUAL et ITIMER_REAL.

Ne pas utiliser les fonctions d'alarme ou UAlarm, vous aurez une faible précision lorsque votre processus obtenir un travail.

Je préfère le Boost bibliothèque minuterie sa simplicité, mais si vous ne voulez pas utiliser les bibliothèques tierces parrty, en utilisant l'horloge () semble raisonnable.

Comme une mise à jour, apparaît que l'horloge Windows () mesure le temps d'horloge murale (avec une précision CLOCKS_PER_SEC)

 http://msdn.microsoft.com/en-us/library/4e2ess30(VS.71).aspx

tandis que sur Linux, il mesure le temps cpu dans les noyaux utilisés par le processus courant

http://www.manpagez.com/man/3/clock

et (il semble, et comme l'a noté l'affiche d'origine) en fait avec moins précision que CLOCKS_PER_SEC, mais peut-être cela dépend de la version spécifique de Linux.

I comme la méthode de soja Hola de ne pas utiliser gettimeofday (). Il me est arrivé sur un serveur exécutant l'administrateur a changé le fuseau horaire. L'horloge a été mis à jour pour afficher la même valeur (correcte) locale. Cela a provoqué le temps de fonction () et gettimeofday () pour passer 2 heures et tous les horodateurs dans certains services se sont retrouvés coincés.

J'ai écrit une classe C++ en utilisant timeb.

#include <sys/timeb.h>
class msTimer 
{
public:
    msTimer();
    void restart();
    float elapsedMs();
private:
    timeb t_start;
};

Fonctions membres:

msTimer::msTimer() 
{ 
    restart(); 
}

void msTimer::restart() 
{ 
    ftime(&t_start); 
}

float msTimer::elapsedMs() 
{
    timeb t_now;
    ftime(&t_now);
    return (float)(t_now.time - t_start.time) * 1000.0f +
           (float)(t_now.millitm - t_start.millitm);
}

Exemple d'utilisation:

#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char** argv) 
{
    msTimer t;
    for (int i = 0; i < 5000000; i++)
        ;
    std::cout << t.elapsedMs() << endl;
    return 0;
}

Sortie sur mon ordinateur est « 19 ». Précision de la classe msTimer est de l'ordre de quelques millisecondes. Dans l'exemple d'utilisation ci-dessus, le temps total d'exécution prise par la boucle de for est suivi. Cette fois inclus le système d'exploitation et de commutation dans le contexte d'exécution de main() en raison de multitâche.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top