Question

EDIT: Je viens de trouver mon problème après avoir écrit ce long message expliquant chaque détail ... Si quelqu'un peut me donner une bonne réponse sur ce que je fais mal et comment puis-je obtenir le temps d'exécution en quelques secondes (en utilisant un flotteur avec 5 décimales environ), je vais marquer que comme acceptée. Astuce:. Le problème était sur la façon dont je l'ai interprété la page man clock_getttime ()

Salut,

Le mot Let j'ai une fonction nommée myOperation que je dois mesurer le temps d'exécution. Pour mesurer, j'utilise clock_gettime() comme il était recommander dans l'un des commentaires.

Mon professeur nous recommande de mesurer N fois afin que nous puissions obtenir un écart-type moyen et médian pour le rapport final. Il nous recommande également exécutons fois myOperation de M au lieu d'un seul. Si myOperation est une opération très rapide, il mesure M fois nous permettent d'avoir une idée du « temps réel » qu'il faut; provoque l'horloge utilisé pourrait ne pas avoir la précision requise pour mesurer une telle opération. Ainsi, l'exécution myOperation qu'une seule fois ou temps de M dépend vraiment si l'opération elle-même prend assez longtemps pour que la précision d'horloge que nous utilisons.

Je vais avoir du mal à faire face à cette fois de M exécution. L'augmentation M diminue (beaucoup) la valeur moyenne finale. Ce qui n'a pas de sens pour moi. Il est comme ça, en moyenne, vous prenez 3 à 5 secondes pour Voyage du point A au point B. Mais vous allez de A à B et de retour à A 5 fois (ce qui en fait 10 fois, la cause de A à B est le même que B à A) et vous mesure. Que vous divisez par 10, la moyenne que vous obtenez est censé être la même moyenne que vous prenez déplacement d'un point A à B, qui est de 3 à 5 secondes.

Voici ce que je veux que mon code pour le faire, mais cela ne fonctionne pas. Si je continue à augmenter le nombre de fois que je vais de A à B et retour A, la moyenne sera inférieure et abaisser chaque fois, il me fait aucun sens.

Assez de théorie, voici mon code:

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

#define MEASUREMENTS 1
#define OPERATIONS   1

typedef struct timespec TimeClock;

TimeClock diffTimeClock(TimeClock start, TimeClock end) {
    TimeClock aux;

    if((end.tv_nsec - start.tv_nsec) < 0) {
        aux.tv_sec = end.tv_sec - start.tv_sec - 1;
        aux.tv_nsec = 1E9 + end.tv_nsec - start.tv_nsec;
    } else {
        aux.tv_sec = end.tv_sec - start.tv_sec;
        aux.tv_nsec = end.tv_nsec - start.tv_nsec;
    }

    return aux;
}

int main(void) {
    TimeClock sTime, eTime, dTime;
    int i, j;

    for(i = 0; i < MEASUREMENTS; i++) {
        printf(" » MEASURE %02d\n", i+1);

        clock_gettime(CLOCK_REALTIME, &sTime);

        for(j = 0; j < OPERATIONS; j++) {
            myOperation();
        }

        clock_gettime(CLOCK_REALTIME, &eTime);

        dTime = diffTimeClock(sTime, eTime);

        printf("   - NSEC (TOTAL): %ld\n", dTime.tv_nsec);
        printf("   - NSEC (OP): %ld\n\n", dTime.tv_nsec / OPERATIONS);
    }

    return 0;
}

Notes: La fonction diffTimeClock ci-dessus est de cette Blog post . Je l'ai remplacé mon vrai opération avec myOperation() parce qu'il ne fait pas de sens pour poster mes fonctions réelles que je dois poster de longs blocs de code, vous pouvez coder facilement un myOperation() avec ce que vous voulez compiler le code si vous le souhaitez.

Comme vous pouvez le voir, OPERATIONS = 1 et les résultats sont les suivants:

 » MEASURE 01
   - NSEC (TOTAL): 27456580
   - NSEC (OP): 27456580

Pour OPERATIONS = 100 les résultats sont les suivants:

 » MEASURE 01
   - NSEC (TOTAL): 218929736
   - NSEC (OP): 2189297

Pour OPERATIONS = 1000 les résultats sont les suivants:

 » MEASURE 01
   - NSEC (TOTAL): 862834890
   - NSEC (OP): 862834

Pour OPERATIONS = 10000 les résultats sont les suivants:

 » MEASURE 01
   - NSEC (TOTAL): 574133641
   - NSEC (OP): 57413

Maintenant, je ne suis pas un wiz de maths, loin de là en fait, mais cela ne fait pas de sens pour moi que ce soit. J'ai déjà parlé avec un ami qui est sur ce projet avec moi et il peut aussi ne pas comprendre les différences. Je ne comprends pas pourquoi la valeur est plus en plus bas quand j'augmente OPERATIONS. L'opération elle-même devrait prendre en même temps (en moyenne bien sûr, pas exactement en même temps), peu importe combien de fois je l'exécuter.

Vous pourriez me dire que cela dépend en fait de l'opération elle-même, les données lues et que certaines données pourraient être déjà dans le cache et bla bla, mais je ne pense pas que ce soit le problème. Dans mon cas, myOperation lit 5000 lignes de texte à partir d'un fichier CSV, séparant les valeurs par ; et en insérant ces valeurs dans une structure de données. Pour chaque itération, je détruire la structure de données et l'initialiser à nouveau.

Maintenant que je pense, je pense aussi que qu'il yEst un temps de mesure de problème avec clock_gettime(), peut-être je ne suis pas l'utiliser à droite. Je veux dire, regardez le dernier exemple, où OPERATIONS = 10000. Le temps total a été 574133641ns, ce qui serait à peu près 0,5s; qui est impossible, il a fallu quelques minutes que je ne pouvais pas supporter regarder l'attente de l'écran et est allé manger quelque chose.

Était-ce utile?

La solution

Vous avez juste besoin de changer votre fonction diffTimeClock() pour retourner le nombre de différence secondes, comme double:

double diffTimeClock(TimeClock start, TimeClock end) {
    double diff;

    diff = (end.tv_nsec - start.tv_nsec) / 1E9;
    diff += (end.tv_sec - start.tv_sec);

    return diff;
}

et le principal changement de routine dTime à un double et les printfs en fonction de:

printf("   - SEC (TOTAL): %f\n", dTime);
printf("   - SEC (OP): %f\n\n", dTime / OPERATIONS);

Autres conseils

On dirait le type TimeClock a deux champs, l'une pour les secondes et un pour nanosecondes. Il n'a pas de sens de diviser tout le champ nanosecondes avec le nombre d'opérations. Vous devez diviser le temps total.

Si vous utilisez un système POSIX où il y a gettimeofday () la fonction que vous pouvez utiliser quelque chose comme ça pour obtenir l'heure actuelle en microsecondes:

long long timeInMicroseconds(void) {
    struct timeval tv;

    gettimeofday(&tv,NULL);
    return (((long long)tv.tv_sec)*1000000)+tv.tv_usec;
}

La raison pour laquelle cela est très pratique est que, pour calculer combien votre fonction a besoin de faire ceci:

long long start = timeInMicroseconds();
... do your task N times ...
printf("Total microseconds: %lld", timeInMicroseconds()-start);

Vous ne devez pas traiter deux entiers, une avec secondes et une avec microsecondes. Ajout et temps soustracteurs travailleront d'une manière évidente.

J'utilise généralement la fonction du temps () pour cela. Il montre l'heure de mur, mais qui est vraiment ce que je me soucie de la fin.

Un Gotcha avec des tests de performance est le système d'exploitation peut mettre en cache les opérations liées au système de fichiers. Ainsi, le deuxième (et plus tard) fonctionne peut être beaucoup plus rapide que la première manche. En général, vous devez tester peut les opérations et le résultat moyen pour obtenir une bonne idée pour les résultats de toutes les modifications apportées. Il y a tellement de variables cela peut vous aider à filtrer le bruit.

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