Pregunta

Estoy escribiendo un juego XNA en el que hago comprobaciones de colisión por píxel. El bucle que comprueba esto lo hace cambiando int y bitwise ORing y generalmente es difícil de leer y entender.

Me gustaría agregar métodos privados como privado bool IsTransparent (int pixelColorValue) para hacer que el bucle sea más legible, pero no quiero la sobrecarga de las llamadas a métodos, ya que esto es muy sensible al rendimiento código.

¿Hay alguna forma de forzar al compilador a incluir esta llamada o lo haré solo espero que el compilador haga esta optimización?

Si no hay una manera de forzar esto, ¿hay una manera de verificar si el método estaba en línea, sin leer el desmontaje? ¿Se mostrará el método en la reflexión si estaba en línea y no existen otros llamadores?

Editar: No puedo forzarlo, ¿puedo detectarlo?

¿Fue útil?

Solución

No, no puedes. Más aún, el que decide sobre la incorporación no es el compilador VS que toma su código y lo convierte en IL, sino el compilador JIT que toma IL y lo convierte en código de máquina. Esto se debe a que solo el compilador JIT sabe lo suficiente sobre la arquitectura del procesador para decidir si colocar un método en línea es apropiado, ya que es una compensación entre la canalización de instrucciones y el tamaño del caché.

Así que incluso buscar en .NET Reflector no te ayudará.

Otros consejos

  

" Puedes verificar   System.Reflection.MethodBase.GetCurrentMethod (). Nombre.   Si el método está en línea, lo hará   devolver el nombre de la persona que llama   en su lugar. "

- Joel Coehoorn

Hay una nueva forma de alentar una incorporación más agresiva en .net 4.5 que se describe aquí: http://blogs.microsoft.co.il/blogs/sasha/archive/2012/01/20/aggressive -inline-en-el-clr-4-5-jit.aspx

Básicamente, es solo una bandera para indicar al compilador que se incorpore en línea si es posible. Desafortunadamente, no está disponible en la versión actual de XNA (Game Studio 4.0) pero debería estar disponible cuando XNA alcance el VS 2012 este año en algún momento. Ya está disponible si de alguna manera estás ejecutando en 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; 
    } 
}

Tenga en cuenta que la XBox funciona de manera diferente.

Un google subió esto:

" El método en línea que mitiga la sobrecarga de una llamada de un método. JIT forma en línea lo que cumple las siguientes condiciones.

  • El tamaño del código IL es de 16 bytes o menos.
  • El comando de bifurcación no se usa (si oración etc.).
  • La variable local no se usa.
  • El manejo de excepciones no ha sido llevado a cabo (prueba, captura, etc.).
  • float no se utiliza como argumento o valor de retorno de un método (probablemente por la Xbox 360, no aplicada).
  • Cuando dos o más argumentos están en una Método, utiliza para el turno. declarado.

Sin embargo, una función virtual no se forma en línea. "

http: //xnafever.blogspot .com / 2008/07 / inline-method-by-xna-on-xbox360.html

No tengo ni idea de si es correcto. ¿Alguien?

No, no puedes.

Básicamente, tampoco puedes hacer eso en la mayoría de los compiladores de C ++ modernos. inline es solo una oferta para el compilador. Es gratis tomarlo o no.

El compilador de C # no realiza ninguna alineación especial en el nivel de IL. El optimizador de JIT es el que lo hará.

¿por qué no usar código inseguro (en línea c como se conoce) y hacer uso de punteros de estilo c / c ++? Esto está a salvo del GC (es decir, no está afectado por la recopilación) pero tiene sus propias implicaciones de seguridad (no se puede usar para internet aplicaciones de zona) pero es excelente para el tipo de cosas que parece que está tratando de lograr, especialmente con el rendimiento y aún más con los arreglos y las operaciones a nivel de bits?

para resumir, ¿quieres rendimiento para una pequeña parte de tu aplicación? Usar código inseguro y hacer uso de punteros, etc. me parece la mejor opción

EDITAR: un poco de arranque? http://msdn.microsoft.com/en-us /library/aa288474(VS.71).aspx

La única forma de verificar esto es obtener o escribir un generador de perfiles, y enganchar a los eventos JIT, también debe asegurarse de que Inlining no esté desactivado como lo está de forma predeterminada al crear perfiles.

Puede detectarlo en tiempo de ejecución con la llamada GetCurrentMethod mencionada anteriormente. Pero, eso parece ser un desperdicio [1]. Lo más fácil de hacer sería ILDASMAR el MSIL y verificarlo allí.

Tenga en cuenta que esto es específicamente para el compilador que se encuentra en línea en la llamada, y se trata en los diversos Reflection docs en MSDN.

  

Si el método que llama al método GetCallingAssembly es expandido en línea por el compilador (es decir, si el compilador inserta el cuerpo de la función en el lenguaje intermedio de Microsoft emitido (MSIL), en lugar de emitir una llamada a la función), el ensamblado devolvió por el método GetCallingAssembly es el ensamblaje que contiene el código en línea. Esto podría ser diferente del ensamblaje que contiene el método original. Para asegurarse de que el compilador no incorpore un método que llame al método GetCallingAssembly, puede aplicar el atributo MethodImplAttribute con MethodImplOptions.NoInlining.

Sin embargo, el JITter también es gratuito para las llamadas en línea, pero creo que un desensamblador sería la única forma de verificar qué se hace y qué no se hace a ese nivel.

Editar: Solo para aclarar algo de confusión en este hilo, csc.exe hará llamadas MSIL en línea - aunque el JITter (probablemente) será más agresivo en él.

[1] Y, por desperdicio, me refiero a (a) que anula el propósito de la alineación (mejor rendimiento) debido a la búsqueda de Reflexión. Y (b), probablemente cambiaría el comportamiento de alineación de modo que ya no esté en línea. Y, antes de que piense que solo puede activar las compilaciones de depuración con un Assert o algo así, tenga en cuenta que no estará en línea durante la depuración, pero puede estar en la versión.

  

¿Hay alguna forma de forzar al compilador a incluir esta llamada o lo haré solo espero que el compilador haga esta optimización?

Si es más barato alinear la función, lo hará. Así que no te preocupes, a menos que tu generador de perfiles diga que en realidad es un problema.

Para más información

Mejoras de JIT en .NET 3.5 SP1

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top