Question

J'écris un jeu XNA dans lequel je vérifie les collisions par pixel. La boucle qui le vérifie le fait en décalant une opération ORing au niveau du bit et est généralement difficile à lire et à comprendre.

Je voudrais ajouter des méthodes privées telles que private bool IsTransparent (int pixelColorValue) pour rendre la boucle plus lisible, mais je ne souhaite pas la surcharge des appels de méthode car elle est très sensible aux performances. code.

Existe-t-il un moyen de forcer le compilateur à intégrer cet appel ou le ferai-je? J'espère seulement que le compilateur effectuera cette optimisation?

S'il n'y a pas de moyen de forcer cela, y a-t-il un moyen de vérifier si la méthode était en ligne, à moins de lire le désassemblage? La méthode sera-t-elle visible si elle était en ligne et qu'aucun autre appelant n'existe?

Modifier: Je ne peux pas le forcer, puis-je le détecter?

Était-ce utile?

La solution

Non, vous ne pouvez pas. Encore plus, celui qui décide de l’inclusion en ligne n’est pas un compilateur VS qui récupère votre code et le convertit en IL, mais un compilateur JIT qui prend IL et le convertit en code machine. En effet, seul le compilateur JIT en sait suffisamment sur l’architecture du processeur pour décider si l’insertion d’une méthode en ligne est appropriée, car c’est un compromis entre le traitement en pipeline des instructions et la taille du cache.

Donc, même regarder dans .NET Reflector ne vous aidera pas.

Autres conseils

  

"Vous pouvez vérifier   System.Reflection.MethodBase.GetCurrentMethod (). Nom.   Si la méthode est en ligne, ce sera   renvoyer le nom de l'appelant   à la place. "

- Joel Coehoorn

Il existe un nouveau moyen d'encourager une intégration plus agressive dans .net 4.5, qui est décrit ici: http://blogs.microsoft.co.il/blogs/sasha/archive/2012/01/20/aggressive -inlining-in-the-clr-4-5-jit.aspx

Fondamentalement, c’est juste un drapeau pour indiquer au compilateur de s’inscrire en ligne si possible. Malheureusement, il n'est pas disponible dans la version actuelle de XNA (Game Studio 4.0), mais devrait l'être lorsque XNA se rapprochera de VS 2012 cette année. Il est déjà disponible si vous utilisez Mono.

[MethodImpl(MethodImplOptions.AggressiveInlining)] 
public static int LargeMethod(int i, int j)
{ 
    if (i + 14 > j) 
    { 
        return i + j; 
    } 
    else if (j * 12 < i) 
    { 
        return 42 + i - j * 7; 
    } 
    else 
    { 
        return i % 14 - j; 
    } 
}

Sachez que la XBox fonctionne différemment.

Un google a indiqué ceci:

"La méthode en ligne qui atténue la surcharge d'un appel d'une méthode. JIT forme un inline qui remplit les conditions suivantes.

  • La taille du code IL est de 16 octets ou moins.
  • La commande de branche n’est pas utilisée (si phrase, etc.).
  • La variable locale n'est pas utilisée.
  • La gestion des exceptions n'a pas été effectué (essayer, attraper, etc.).
  • float n'est pas utilisé comme argument ou renvoyer la valeur d'une méthode (probablement par la Xbox 360, non appliquée).
  • quand deux ou plusieurs arguments sont dans un méthode, il utilise pour le tour déclarée.

Cependant, une fonction virtuelle n'est pas transformée en un inline. "

http: //xnafever.blogspot .com / 2008/07 / méthode-en-ligne-par-xna-on-xbox360.html

Je ne sais pas s'il a raison. Quelqu'un?

Non, vous ne pouvez pas.

En gros, vous ne pouvez pas faire cela avec la plupart des compilateurs C ++ modernes. inline est simplement une offre au compilateur. C'est gratuit de le prendre ou pas.

Le compilateur C # ne fait pas d’inline spécial au niveau IL. L’optimiseur JIT est celui qui le fera.

pourquoi ne pas utiliser du code non sécurisé (inline c comme son nom l'indique) et utiliser des pointeurs de style c / c ++, il est protégé du GC (c'est-à-dire qu'il n'est pas affecté par la collection) mais comporte ses propres implications en matière de sécurité zone apps), mais est excellent pour le genre de choses que vous essayez d’atteindre, en particulier avec les performances et plus encore avec les tableaux et les opérations au niveau des bits?

Pour résumer, vous voulez des performances pour une petite partie de votre application? utiliser du code non sécurisé et utiliser des pointeurs, etc. me semble être la meilleure option

EDIT: un peu un démarreur? http://msdn.microsoft.com/en-us /library/aa288474(VS.71).aspx

La seule façon de vérifier cela consiste à obtenir ou à écrire un profileur et à vous connecter aux événements JIT, vous devez également vous assurer que la mise en ligne n'est pas désactivée telle quelle par défaut lors du profilage.

Vous pouvez le détecter au moment de l'exécution avec l'appel GetCurrentMethod susmentionné. Mais cela semble être un peu une perte [1]. La chose la plus facile à faire serait de simplement mettre ILDASM dans le MSIL et d’y accéder.

Notez que cela concerne spécifiquement le compilateur qui insère l'appel, et est traité dans les divers Reflection : documentation sur MSDN.

  

Si la méthode qui appelle la méthode GetCallingAssembly est développée en ligne par le compilateur (c'est-à-dire, si le compilateur insère le corps de la fonction dans le langage intermédiaire Microsoft (MSIL) émis, plutôt que d'émettre un appel de fonction), l'assembly renvoie Par la méthode GetCallingAssembly, l’assembly contenant le code en ligne. Cela peut être différent de l'assembly qui contient la méthode d'origine. Pour vous assurer qu'une méthode qui appelle la méthode GetCallingAssembly n'est pas insérée par le compilateur, vous pouvez appliquer l'attribut MethodImplAttribute avec MethodImplOptions.NoInlining.

Cependant, le JITter est également gratuit pour les appels en ligne - mais je pense qu'un désassembleur serait le seul moyen de vérifier ce qui est fait et ce qui ne l'est pas à ce niveau.

Modifier: Juste pour dissiper une certaine confusion dans ce fil, csc.exe sera un appel MSIL en ligne - bien que le JITter soit (probablement) plus agressif.

[1] Et, par gaspillage - je veux dire que (a) cela va à l’encontre du but de l’inline (meilleure performance) en raison de la recherche de Reflection. Et (b), cela changerait probablement le comportement de la ligne afin qu’elle ne soit plus en ligne de toute façon. Et, avant de penser que vous pouvez simplement l'activer, les versions Debug avec un Assert ou quelque chose du genre - réalisez que cela ne sera pas en ligne pendant Debug, mais peut-être dans Release.

  

Existe-t-il un moyen de forcer le compilateur à intégrer cet appel ou le ferai-je? J'espère seulement que le compilateur effectuera cette optimisation?

S'il est meilleur marché d’intégrer la fonction, ce sera le cas. Ne vous inquiétez donc pas, à moins que votre profileur ne vous dise que c'est un problème.

Pour plus d'informations

Améliorations de JIT dans .NET 3.5 SP1

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