Génération de code dans l'API de profilage
Cette rubrique décrit le flux de code MSIL (Microsoft Intermediate Language) en code natif et comment un profileur peut contrôler la génération de code.
Génération de code automatique et génération de code manuelle
Le MSIL dans un assembly .NET Framework peut être compilé en code natif de l'une des deux façons suivantes :
Compilation manuelle : l'outil Native Image Generator (NGen.exe) peut être utilisé pour créer une image native.
Compilation automatique : le Common Language Runtime (CLR) peut exécuter une compilation juste-à-temps (JIT) au moment de l'exécution.
L'outil NGen.exe et le compilateur JIT fournissent tous deux des indicateurs qui contrôlent la génération de code.
Lorsqu'un assembly est chargé, le CLR recherche d'abord une image native pour l'assembly. S'il ne trouve pas d'image native avec le bon jeu d'indicateurs de génération du code, le CLR effectue une compilation JIT des fonctions dans l'assembly dans la mesure où elles sont requises en cours d'exécution. Même quand une image native est trouvée et chargée, le CLR peut effectuer la compilation JIT de quelques-unes des fonctions dans l'assembly.
Contrôle de profileur sur la génération de code
Le profileur utilise les indicateurs dans le tableau suivant pour contrôler la génération de code.
Indicateur |
Effet |
---|---|
COR_PRF_USE_PROFILE_IMAGES |
(Requiert la version 2.0 du .NET Framework.) Fait en sorte que la recherche d'images natives trouve des images améliorées par profileur (ngen /profile). Si la recherche ne trouve pas d'image native améliorée par profileur pour un assembly donné, le CLR effectue à la place la compilation JIT des méthodes dans cet assembly, dans la mesure où elles sont requises. N'a aucun effet sur le code compilé par le JIT. |
COR_PRF_DISABLE_INLINING |
N'a aucun effet sur la recherche d'images natives. Dans la compilation JIT, désactive la fonction inline. Toutes les autres optimisations demeurent effectives. |
COR_PRF_DISABLE_OPTIMIZATIONS |
N'a aucun effet sur la recherche d'images natives. Dans la compilation JIT, désactive toutes les optimisations, y compris la fonction inline. |
COR_PRF_MONITOR_ENTERLEAVE |
Fait en sorte que la recherche d'images natives trouve des images améliorées par profileur (ngen /profile). Dans la compilation JIT, insère des raccordements d'entrée/sortie dans le code généré. |
COR_PRF_MONITOR_CODE_TRANSITIONS |
Fait en sorte que la recherche d'images natives trouve des images améliorées par profileur (ngen /profile). Dans la compilation JIT, insère des raccordements à des points de transition managés/non managés. |
Profileurs et images natives
Lorsque l'outil NGen.exe crée une image native, il effectue une grande part du travail que le CLR exécute en général au moment de l'exécution (par exemple, chargement de classes et compilation de fonctions). En conséquence, dans les cas où le travail a été fait lors de l'exécution de NGen, les rappels de profileur suivants ne seront pas reçus au moment de l'exécution :
Images natives améliorées par profileur
La création d'une image native à l'aide de l'outil NGen.exe active un jeu d'indicateurs de génération de code qui simplifient le profilage de l'image, comme suit :
Des raccordements d'entrée/de sortie sont insérés dans le code.
Des raccordements de transition managés/non managés sont insérés dans le code.
Des notifications ICorProfilerCallback::JITCachedFunctionSearchStarted et ICorProfilerCallback::JITCachedFunctionSearchFinished sont émises chaque fois qu'une fonction dans l'image native est appelée pour la première fois.
Des notificationICorProfilerCallback::ClassLoadStarted et ICorProfilerCallback::ClassLoadFinished sont émises chaque fois qu'une classe dans l'image native est utilisée pour la première fois.
Considérations sur les performances
La méthode vous utilisez pour profiler votre application générée par NGen dépend de deux considérations : les données que vous devez acquérir, et l'effet des raccordements de profilage incorporés sur votre application.
Comme expliqué au début de cette rubrique, il existe deux scénarios de profilage NGen de base :
Les images natives normales (images générées par NGen sans raccordements de profilage) : ces images n'entraînent pas de charge de profilage. Toutefois, les rappels de chargement/déchargement des classes ne sont pas disponibles pour les images natives normales. Pour gérer cette situation, un profileur qui ne souhaite pas demander des images natives améliorées par profileur devra rassembler des données à propos de FunctionID ou ClassID à mesure que les ID sont rencontrés. Par exemple, un profileur d'échantillonnage ne rencontrera pas de FunctionID lors de sa première compilation par JIT ou de son premier chargement à partir d'une image générée par l'outil NGen, car les rappels de chargement/déchargement de classes ne sont pas émis pour les images normales générées par l'outil NGen. Le profileur rencontrera le FunctionID ultérieurement, lorsqu'un échantillon indique que le processus s'exécutait à un pointeur d'instruction (IP) à l'intérieur du corps du code compilé de la fonction. Dans ce cas, le profileur pourrait demander des informations sur la fonction pendant l'échantillonnage, ou il pourrait enregistrer l'FunctionID ou son jeton de métadonnées associé à des fins d'interrogation ultérieure. Par conséquent, le profileur demandera des informations sur le FunctionID ou ClassID seulement au dernier moment possible (lorsqu'il détecte que l'ID est réellement utilisé) et non pas avant, lorsque l'ID est produit la première fois.
Les images natives améliorées par profileur (images générées par l'outil NGen avec des raccordements de profilage incorporés) : ces images sont plus grandes, et diffèrent considérablement des images normales. De plus, le comportement de l'application peut être différent lorsqu'elle inclut des raccordements de profileur. Par conséquent, vous devez utiliser des images natives améliorées par profileur uniquement si la performance potentielle et les conséquences comportementales sont acceptables (en termes de charge).