5 votes

Performances du C++, optimisation du compilateur, fonction vide dans .cpp

J'ai une classe très basique, nommée Basic, utilisée dans presque tous les autres fichiers d'un plus grand projet. Dans certains cas, il est nécessaire d'avoir une sortie de débogage, mais en mode release, cela ne devrait pas être activé et être un NOOP.

Actuellement, il existe une définition dans l'en-tête, qui active ou désactive un makro, en fonction du paramètre. Il s'agit donc bien d'un NOOP, lorsqu'il est désactivé. Je me demande, si j'ai le code suivant, si un compilateur (MSVS / gcc) est capable d'optimiser l'appel de fonction, de sorte qu'il soit à nouveau un NOOP. (En faisant cela, le commutateur pourrait être dans le .cpp et la commutation sera beaucoup plus rapide, en termes de temps de compilation/liaison).

--Header--
void printDebug(const Basic* p);

class Basic {
   Basic() {
      simpleSetupCode;

      // this should be a NOOP in release, 
      // but constructor could be inlined
      printDebug(this);
   }
};
--Source--
// PRINT_DEBUG defined somewhere else or here
#if PRINT_DEBUG
void printDebug(const Basic* p) {
   // Lengthy debug print
}
#else
void printDebug(const Basic* p) {}
#endif

1voto

Comme pour toutes les questions de ce type, la réponse est la suivante : si cela vous importe vraiment, essayez l'approche et examinez le langage assembleur émis.

1voto

Alex Farber Points 19387

Le compilateur peut éventuellement optimiser ce code, s'il connaît l'implémentation de la fonction printDebug au moment de la compilation. Si printDebug se trouve dans un autre module objet, il est possible qu'il soit optimisé uniquement par l'éditeur de liens, en utilisant l'optimisation de l'ensemble du programme. Mais le seul moyen de le vérifier est de lire le code Assembleur généré par le compilateur. Si vous avez déjà la macro PRINT_DEBUG, vous pouvez l'étendre de la même manière que TRACE est défini :

#define PRINT\_DEBUG    // optional
#ifdef PRINT\_DEBUG
#define PRINT\_DEBUG\_CALL(p) printDebug(p)
#else
#define PRINT\_DEBUG\_CALL(p)
#endif

void printDebug(const Basic\* p);

class Basic {
   Basic() {
      simpleSetupCode;

      // this should be a NOOP in release, 
      // but constructor could be inlined
      PRINT\_DEBUG\_CALL(this);
   }
};
--Source--
// PRINT\_DEBUG defined somewhere else or here
#if PRINT\_DEBUG
void printDebug(const Basic\* p) {
   // Lengthy debug print
}
#endif

1voto

Actuellement, la plupart des optimisations sont effectuées au moment de la compilation. Certains compilateurs comme LLVM sont capables d'optimiser au moment de la liaison. C'est une idée vraiment intéressante. Je vous suggère d'y jeter un coup d'oeil.

En attendant ce genre d'optimisation, ce que vous pouvez faire est le suivant. Définissez une macro qui vous permet d'inclure l'instruction suivante selon que DEBUG est défini ou non.

#ifdef DEBUG
#define IF_DEBUG (false) {} else
#else
#define IF_DEBUG 
#endif

Vous pouvez l'utiliser comme suit

   Basic() {
      simpleSetupCode;

      // this should be a NOOP in release, 
      // but constructor could be inlined
      IF_DEBUG printDebug(this);
   }

qui est déjà beaucoup plus lisible que

   Basic() {
      simpleSetupCode;

      // this should be a NOOP in release, 
      // but constructor could be inlined
#if DEBUG
      printDebug(this);
#endif
   }

Notez que vous pouvez l'utiliser comme s'il s'agissait d'un mot-clé.

IF_DEBUG {
   printDebug(this);
   printDebug(thas);
}

1voto

drawnonward Points 35444
#if PRINT_DEBUG
#define printDebug _real_print_debug
#else
#define printDebug(...)
#endif

De cette façon, le préprocesseur éliminera tout le code de débogage avant même qu'il n'atteigne le compilateur.

0voto

Mawg Points 7387

Errm, pourquoi ne pas utiliser différemment la macro du pré-processeur ?

Juste sur le dessus de ma tête, quelque chose comme :

  #define DEBUG_TRACE(p)
  #ifdef PRINT_DEBUG
    printDebug(p);
  #else
    ;
  #endif

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X