Question

Je voudrais utiliser la garde de portée en C afin de faire du profilage.

Je voudrais savoir combien de temps je passe dans une fonction. Voici ce que je fais:

int function() {

  tic();

  ... do stuff ...
  if (something)
  {
    toc();
    return 0;
   }

  toc();
  return 1;
}

Je dois placer une déclaration de toc chaque fois que je quitte la fonction. Je voudrais le faire sans avoir à copier coller partout toc. Est-il un moyen générique de le faire, en utilisant une macro ou quelque chose? Aussi je ne veux pas changer la façon dont la fonction est appelée, car il y a beaucoup de fonctions que je dois le profil.

Merci

Était-ce utile?

La solution

Cela ne change pas la façon dont la fonction est appelée. utilisez probablement pas grand-chose si vous voulez être en mesure de profil chaque fonction, cependant.

static inline int real_function() {
    // previous contents of function(), with no tic or toc
}

int function() {
    tic();
    int r = real_function();
    toc();
    return r;
}

Comme tout le monde dit: utiliser un profileur, il vous fera économiser beaucoup d'efforts à long terme. Comme ils ne disent pas:. Si votre plate-forme a un

Si elle n'a pas, le plus simple est de dire (en règle de codage) qui fonctionne doivent avoir un seul point de sortie, et que le point de sortie doit être via votre macro. Ensuite, vous pouvez instrumenter manuellement toutes vos fonctions avec le code à l'entrée et la sortie. Fonctions héritées avec de multiples retours peuvent être emballés comme ci-dessus.

De plus, gardez à l'esprit quand vous faites quelque chose comme ce que votre compilateur peut mess vous. Vous pouvez écrire ceci:

tic();
do_something();
int i = something_else();
toc();
return i;

Si le compilateur détermine que something_else n'a pas d'effets secondaires, alors même si something_else prend beaucoup de temps, il pourrait transformer le code en ceci:

tic();
do_something();
toc();
return something_else();

Et vos données de profil sous-estimeront le temps passé dans votre fonction. Une autre raison pour laquelle il est si bon d'avoir un vrai profileur - il peut coopérer avec le compilateur.

Autres conseils

Vous pouvez définir une macro comme:

#define TOC_RETURN(x) \
    do { \
    toc(); \
    return x; \
    } while(0)

qui devrait fonctionner partout où vous le mettez. Ensuite, vous pouvez automatiser le remplacement return *; avec TOC_RETURN(*).

Pourquoi ne pas utiliser un outil de profilage réel, comme gprof ?

Vous pourriez juste " Redéfinir " retour via une macro: (voir s'il vous plaît Disclaimer)

#include <stdio.h>

void tic() { printf("tic\n"); }
void toc() { printf("toc\n"; }

#define return toc(); return
int foo() {
    tic();

    return 0;
}
#undef return

int main() {
    foo();
    return 0;
}

Disclaimer: Cela peut être considéré comme laid et hacky parce que:

  • Il ne fonctionnera pas pour les fonctions vides sauf si vous utilisez retour;. -statements
  • Il pourrait ne pas être portable / standard, même si cela fonctionne sur MSVC8.
  • Il ne faut pas définir des mots clés.

Je ne recommanderais pas une macro pour cela. Vous profiler le code une seule fois dans un certain temps, et le remplacement de « retour » avec une macro spéciale juste à cet effet rend le code moins lisible.

est-il pas mieux à faire comme suit?

tic();
call_function();
toc();

"gère automatiquement tous les points de sortie" de la fonction.

P.S. Pourquoi ne pas utiliser un profileur?

Un profileur réel n'a pas besoin de vous pour modifier le code, il suffit de le compiler avec le profilage activé.

Hmm, peut-être envelopper l'appel de fonction dans une macro (famille de macros, vraiment)? Voici un qui ne prend aucun argument et retourne retVal:

// define the wrapper for name
#define DEFTIMECALL0(Retval,name) \
    Retval timed##name() \
    { \
        Retval ret;
        tic(); \
        ret = name(); \
        toc(); \
        return ret; \
    }

Vous aurez besoin de macros pour chaque arité de fonction des appels Émettre, avec une version de retour retVal et non avenue.

Modifier Peut-être il n'y a même pas un point dans la définition de la fonction enveloppe, et mieux d'avoir juste une famille de macros (encore une fois, pour chaque arité et le retour des versions de type / vide) qui enveloppent un appel de fonction dans un tic / toc directement sur les callsites

Ne pas avoir peur de instrumentant profileurs, qui font essentiellement pour vous.

scroll top