
La publication présente une implémentation logicielle d'outils intégrés pour collecter et accumuler des informations métriques sur l'exécution des applications écrites en C / C ++ / C #.
L'essence de l'approche décrite est basée sur l'inclusion de «points de contrôle» dans le code de programme de l'application pour extraire des données sur le temps d'exécution des composants structurels: méthodes, fonctions et blocs {}. Les informations métriques extraites sont accumulées dans une base de données interne, dont le contenu à la fin de l'application est converti en un formulaire de rapport texte enregistré dans un fichier. La pertinence d'utiliser les moyens de contrôle intégré du temps d'exécution est due à la nécessité d'identifier les zones problématiques du code, d'analyser les causes de la dégradation temporaire de l'application: complète ou partielle, ou apparaissant sur certains ensembles de données sources.
Les exemples de code source C ++ / C # donnés illustrent les implémentations possibles de l'approche décrite.
Présentation
Le développement d'une application logicielle à chaque itération (par exemple, la sortie de la prochaine version) de son développement évolutif comprend les étapes de base suivantes:
- développement et test de fonctionnalités;
- optimisation des ressources consommées de RAM;
- stabilisation des métriques d'exécution.
Ces étapes nécessitent une quantité importante de développeurs non seulement créatifs (tels que le développement et la mise en œuvre d'algorithmes efficaces, la construction d'une architecture logicielle flexible, etc.), mais également un travail de routine. Cette dernière catégorie comprend les activités visant à stabiliser les mesures de temps pour l'exécution des applications. Dans de nombreux cas, il s'agit d'une procédure assez pénible lorsque les développeurs sont confrontés à une dégradation, qui est une conséquence de l'extension des fonctionnalités du produit logiciel, de la reconstruction de l'architecture logicielle et de l'émergence de nouveaux threads dans l'application. Dans le même temps, les sources de dégradation nécessitent certains efforts pour les détecter, ce qui est obtenu non seulement par la grande industriosité et la responsabilité des développeurs (condition nécessaire), mais aussi par la composition des outils utilisés à ces fins (condition suffisante).
L'une des approches efficaces pour résoudre le problème de l'analyse des métriques de temps d'application est l'utilisation de produits logiciels spécialisés, par exemple GNU
gprof . L'analyse des rapports générés par de tels outils vous permet d'identifier les «goulots d'étranglement» (méthodes et fonctions de classe), qui représentent une quantité importante de temps passé à exécuter l'application dans son ensemble. Dans le même temps, la validité du temps consacré à l'exécution des méthodes et procédures est certes nuancée par les développeurs.
Il convient également de noter que les produits logiciels de cette classe, en règle générale, effectuent une analyse métrique du temps d'exécution du code de programme aux niveaux des méthodes des classes et des fonctions, en ignorant les niveaux inférieurs (mais néanmoins significatifs du point de vue de l'analyse du problème):
{...}, pour, tandis que do-till, if - else, blocs
try-catch , à l'intérieur desquels des dépenses non moins importantes de temps d'exécution se produisent.
Ensuite, le contenu principal de l'une des solutions possibles pour la mise en œuvre d'outils de contrôle d'exécution intégrés visant à extraire et à accumuler des informations détaillées sur les métriques de temps des blocs logiciels contrôlés avec la génération ultérieure de rapports pour les développeurs est examiné.
Méthodes de récupération des données d'exécution
La fonctionnalité de toute application logicielle peut être interprétée comme une
machine abstraite avec un ensemble fini d'
états uniques
{St} et de transitions
{Tr} entre eux.
Dans le cadre de cette approche, tout flux d'exécution dans l'application doit être interprété comme une séquence ordonnée de ses états et des transitions entre eux. Dans ce cas, l'estimation des coûts de temps d'exécution est effectuée en additionnant les métriques de temps sur l'ensemble des états passés sans tenir compte des coûts des transitions d'un état à un autre - en tant que valeurs négligeables.
L'extraction et l'accumulation de données sur le temps d'exécution de l'application aux points de contrôle spécifiés est la tâche principale résolue par les outils de contrôle intégrés décrits ci-dessous.
Pour chaque point d'arrêt déclaré dans le code source en plaçant
Macro
PROFILE_ENTRY C ++, le nombre de passes lors de l'exécution de l'application est enregistré, ainsi que la métrique de temps - la durée totale pendant laquelle l'application était dans l'état à partir du moment où le point de contrôle est passé au niveau suivant de la hiérarchie du programme (y compris un bloc, une méthode de classe, une fonction, etc.) comme illustré dans le schéma ci-dessous.
Le contrôle des points de contrôle (enregistrement initial et calcul de leurs métriques de temps) est effectué par l'objet
'timeManager' , qui est créé en une seule instance. Chaque événement de passage du point de contrôle est fixé par l'objet
'timeManager', et lors de la première passe il est enregistré par lui comme observable comme
'registerEntry' .
Au moment de chaque passage du point de contrĂ´le, un
timerObject est créé, fixant l'heure de sa création. Le temps d'exécution est fixé au point de contrôle lorsque l'application quitte le niveau actuel de la hiérarchie logicielle. À ce moment, le timerObject de l'objet est automatiquement détruit, ce qui s'accompagne du calcul de sa «durée de vie» T. Par conséquent, le
timeManager augmente le nombre de fois que le point de contrĂ´le passe et le temps qu'il y passe par
T. Pour tous les points de contrôle définis,
timeManager accumule des données avec la publication ultérieure d'un rapport à la fin de l'application.

Vous trouverez ci-dessous le code C ++ source qui implémente les outils intégrés pour contrôler le temps d'exécution de l'application.
La structure de l'application de démonstration est illustrée ci-dessous, illustrant l'utilisation des outils de contrôle d'exécution intégrés à titre d'exemple, ainsi qu'un tableau des résultats obtenus (pour plus de détails, voir l'
annexe 1. Code source de l'application de démonstration ).


Section
Addendum 2. Le code source des moyens du contrôle intégré du temps d'exécution de l'application C # présente une implémentation similaire des moyens du contrôle intégré en C #.
L'auteur utilise des paires de
TimeWatcher.StartWatch () et
TimeWatcher.StopWatch () pour profiler le temps d'exécution de méthodes et procédures laborieuses (d'un point de vue informatique) dans le cadre du produit logiciel
Delta Design développé par
EREMEX - un système de conception assistée par ordinateur pour les équipements électroniques.
Vous trouverez ci-dessous un exemple de bref rapport sur les mesures de temps de l'une des fonctionnalités du produit mentionné.
Brèves conclusions
Les outils décrits peuvent être utilisés pour collecter des données sur le temps d'exécution d'une application dans différentes parties de son code de programme, en particulier, ils permettent:
- collecter et accumuler des données sur les métriques de temps des threads d'exécution dans l'application;
- effectuer des estimations du temps d'exécution du code de programme exactes aux constructions de langage élémentaire;
- gérer le volume des données extraites en activant et désactivant les outils de contrôle intégrés sur les sections correspondantes des flux d'exécution d'application;
- développer et appliquer des tests de régression qui surveillent la stabilité (et détectent la dégradation) des métriques de temps d'application.
En conclusion, il convient de noter qu'en dehors du champ d'application de cette publication, il y avait des questions concernant l'application des outils de contrôle intégrés décrits dans le contexte des applications de
multithreading et aucune analyse de l'exactitude des données obtenues par métrique de temps n'a été présentée sous aucune forme. Ce dernier est dû au fait qu'en pratique, lors de l'identification des causes de dégradation temporaire d'une application, les données sur
la répartition relative des coûts de temps d'exécution entre les composants logiciels de l'application sont principalement pertinentes
. À cet égard, les questions de l'exactitude des données obtenues s'effacent au second plan.
Annexe 1. Code source de l'application de démonstration
INITIALIZE_PROFILER int main(int argc, char * argv[]) {
Supplément 2. Code source des applications C # de contrôle d'exécution intégrées