Question

Je l'ai observé beaucoup de code « pile introspective » dans les applications qui reposent souvent implicitement sur leurs méthodes contenant pas étant inline pour leur exactitude. Ces méthodes impliquent souvent des appels à:

  • MethodBase.GetCurrentMethod
  • Assembly.GetCallingAssembly
  • Assembly.GetExecutingAssembly

Maintenant, je trouve les informations entourant ces méthodes pour être très déroutant. Je l'ai entendu dire que l'exécution ne sera pas inline une méthode qui appelle GetCurrentMethod, mais je ne peux pas trouver toute la documentation à cet effet. Je l'ai vu messages sur StackOverflow à plusieurs reprises, comme celui-ci , ce qui indique le CLR ne pas inline appels inter-assemblage, mais le GetCallingAssembly documentation indique clairement le contraire.

Il y a aussi le [MethodImpl(MethodImplOptions.NoInlining)] tant décrié, mais je ne suis pas sûr si le CLR considère cela comme une « demande » ou une « commande ».

Notez que je demande au sujet inline éligibilité du point de vue du contrat, pas quand les implémentations actuelles de la baisse des JITter d'examiner les méthodes en raison des difficultés de mise en œuvre ou sur lorsque le jITter se termine finalement choisir en ligne une méthode admissible après évaluation des compromis. J'ai lu cette et cette , mais ils semblent être plus concentré sur les deux dernières les points (on passait les mentions de MethodImpOptions.NoInlining et "instructions iL exotiques", mais ceux-ci semblent être présentés comme heuristiques plutôt que comme obligations ).

Quand le CLR autorisés à inline?

Était-ce utile?

La solution

Il est un détail de mise en œuvre de la gigue, x86 et x64 frousse ont des règles légèrement différentes. Ceci est négligemment documenté dans les messages de blog des membres de l'équipe qui a travaillé sur la gigue, mais les équipes se réservent certainement le droit de modifier les règles. On dirait que vous les trouve déjà.

méthodes inline d'autres assemblées est très certainement pris en charge, beaucoup de classes .NET fonctionnerait assez lamentablement si cela était pas le cas. Vous pouvez le voir au travail lorsque vous regardez le code machine généré pour Console.WriteLine (), il obtient souvent inline lorsque vous passez une chaîne simple. Pour voir par vous-même, vous devez passer à l'accumulation des rejets et modifier une option de débogage. Outils + Options, Debugging, Général, décochez "l'optimisation de la charge JIT Suppress du module".

Il n'y a par ailleurs aucune raison de considérer MethodImpOptions.NoInlining décrié, il est à peu près pourquoi il existe en premier lieu. Il est en effet utilisé intentionnellement dans le cadre de .NET sur un bon nombre de petites méthodes publiques qui font appel à une méthode d'assistance interne. Il fait des traces de pile d'exception plus facile à diagnostiquer.

Autres conseils

Hans réponse malgré Passant, ici d'abord quelques conseils à partir de 2004, et plus bas un peu plus d'informations à jour. Ils sont sujets à changement, mais ils vous donnent une idée sur ce qu'il faut rechercher si vous souhaitez effectuer une méthode admissible pour inline:

  

le JIT ne sera pas en ligne:

     
      
  • Méthodes marquées MethodImplOptions.NoInlining
  •   
  • Méthodes plus grande que 32 octets de IL
  •   
  • Les méthodes virtuelles
  •   
  • Les méthodes qui prennent un grand type de valeur en tant que paramètre
  •   
  • Méthodes sur les classes MarshalByRef
  •   
  • Méthodes avec flowgraphs compliquées
  •   
  • Méthodes de réunion, d'autres critères plus exotiques
  •   

En particulier, il est MethodImplOptions.AggressiveInlining , qui est censé lever les 32 octets limite (ou quoi que ce soit ces jours-ci et pour votre plate-forme).

.Net 3.5 heuristiques ajouté que l'aider à déterminer si

Alors que Hans' répondre est correcte, il y a une omission, pas nécessairement lorsqu'une méthode est inlining, mais quand une méthode est pas .

Résumé et méthodes virtuelles ne sont pas inlining dans le CLR .

Il est important de noter qu'il rogne les conditions dans lesquelles une méthode peut être inline.

Il y a plus d'informations sur inline de MethodBase.GetCurrentMethod sur ce fil http: //prdlxvm0001.codify.net/pipermail/ozdotnet/2011-March/009085.html

Paraphrasant fortement, il indique que le RefCrawlMark ne pas arrêter la méthode d'appel étant inline. Cependant, RequireSecObject a le côté affecte d'arrêter l'appelant étant inline.

En outre, les méthodes et Assembly.GetCallingAssembly Assembly.GetExecutingAssembly n'ont pas cet attribut.

Il y avait un article publié sur MSDN en 2003 appelé écriture à haute performance Managed Apps qui couvre les contours plusieurs critères assez clairement:

  • Les méthodes qui sont supérieures à 32 octets de IL ne sera pas inline.
  • Les fonctions virtuelles ne sont pas inline.
  • Les méthodes qui ont le contrôle de flux complexe ne sera pas en doublé. le contrôle de flux complexe est un contrôle de flux autre que si / alors / autre; dans ce cas, interrupteur ou tout.
  • Les méthodes qui contiennent des blocs d'exception de traitement ne sont pas inline, bien que les méthodes qui jettent des exceptions sont toujours candidats à inline.
  • Si l'un des arguments formels de la méthode sont struct, la méthode ne sera pas inline.

article de blog de Sacha Goldshtein en 2012 sur inline agressif CLR a beaucoup du même avis.

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