38 votos

¿Por qué es inline considera más rápido que una llamada a una función?

Ahora, yo sé que es porque no hay la sobrecarga de llamar a una función, pero es la sobrecarga de llamar a una función que realmente pesado (y vale la pena el sobredimensionamiento de tenerlo entre líneas) ?

Por lo que puedo recordar, cuando se llama a una función, digamos f(x,y), x e y se inserta en la pila, y el puntero de pila salta a un bloque vacío, y comienza la ejecución. Sé que esto es un poco de una simplificación excesiva, pero me estoy perdiendo algo? Un par de empujones y de un salto para llamar a una función, es en realidad mucho sobrecarga?

Quiero saber si me estoy olvidando de algo, gracias!

58voto

AndreyT Puntos 139512

Aparte del hecho de que no hay ninguna llamada (y por lo tanto no hay gastos asociados, como parámetro de preparación antes de la llamada y la limpieza después de la llamada), hay otra ventaja importante de los inline. Cuando el cuerpo de la función es en línea, que pueden ser re-interpretado en el contexto específico de la persona que llama. Esto podría permitir la entrada inmediata al compilador para reducir y optimizar el código.

Para un ejemplo sencillo, esta función

void foo(bool b) {
  if (b) {
    // something
  }
  else {
    // something else
  }
}

se requieren real de ramificación si se llama como un no-alineada de la función

foo(true);
...
foo(false);

Sin embargo, si las llamadas son en línea, el compilador inmediatamente será capaz de eliminar la ramificación. Esencialmente, en el caso anterior inline permite al compilador para interpretar el argumento de la función como una constante en tiempo de compilación (si el parámetro es una constante en tiempo de compilación) - algo que generalmente no es posible con los no-alineada funciones.

Sin embargo, no es ni remotamente se limita a eso. En general, las oportunidades de optimización de habilitado de inline son significativamente más largo alcance. Para otro ejemplo, cuando el cuerpo de la función está alineada en el específico contexto del llamador, el compilador en el caso general será capaz de propagar la conocida aliasing relacionados con las relaciones presentes en el código de llamada en la línea el código de la función, por lo que es posible optimizar la función del código mejor.

De nuevo, los ejemplos son numerosos, todos ellos derivados del hecho básico de que entre líneas llamadas están inmersos en el específico contexto del llamador, lo que permite diversas inter-contexto optimizaciones, lo cual no sería posible con los no-alineadas calles. Con inline, básicamente, conseguir muchas versiones individuales de su función original, cada versión está diseñado y optimizado de forma individual para cada llamante contexto. El precio de la que es, obviamente, el peligro potencial de código de hinchazón, pero si se utiliza correctamente, puede proporcionar notables beneficios en el rendimiento.

25voto

"Un par de empujones y de un salto para llamar a una función, es en realidad mucho sobrecarga?"

Depende de la función.

Si el cuerpo de la función es un código máquina de la instrucción, de la llamada y volver a la sobrecarga puede ser de muchos, muchos cientos de %. Decir, 6 veces, un 500% por encima. Entonces, si el programa se compone de nada pero un trillón de llamadas a la función, sin inline ha aumentado el tiempo de ejecución en un 500%.

Sin embargo, en la otra dirección inline puede tener un efecto perjudicial, por ejemplo, porque el código que sin inline caben en una página de memoria no.

Así que la respuesta es siempre cuando se trata de la optimización, la primera de toda MEDIDA.

Saludos y hth.,

11voto

Pontus Gagge Puntos 12950

No hay ninguna llamada y de la pila de la actividad, lo que sin duda guarda un par de ciclos de CPU. En las modernas CPU, código de la localidad que también importa: hacer una llamada puede vaciar la instrucción de la tubería y de la fuerza de la CPU para esperar la memoria que se obtienen. Esto importa mucho en estrecha lazos, ya que la memoria principal es mucho más lento que los modernos de la CPU.

Sin embargo, no te preocupes acerca de inline si el código es sólo ser llamado un par de veces en su aplicación. La preocupación, mucho, si es que se llama millones de veces, mientras que el usuario espera por las respuestas!

11voto

sbi Puntos 100828

El clásico candidato para inline es un descriptor de acceso, como std::vector<T>::size().

Con inline permitido que esta es sólo la recuperación de una variable de memoria, es probable que una única instrucción en cualquiera de las arquitecturas. Los "pocos de empuje y de un salto" (además de la devolución) es fácilmente varias veces como mucho.

A esto se añade el hecho de que, cuanto más código es visible a la vez para un optimizador, la mejor que puede hacer su trabajo. Con un montón de alineaciones, se ve un montón de código a la vez. Eso significa que podría ser capaz de mantener el valor en un registro de CPU, y completamente repuesto el costoso viaje a la memoria. Ahora podemos tomar alrededor de una diferencia de varios órdenes de magnitud.

Y entonces theres plantilla de meta-programación. A veces esto se traduce en llamar a muchas pequeñas funciones de forma recursiva, sólo para obtener un único valor al final de la recursividad. (Piense en ir a buscar el valor de la primera entrada de un tipo específico en una tupla con decenas de objetos). Con inline habilitado, el optimizador puede acceder directamente a ese valor (que, recordemos, puede ser en un registro), colapso de decenas de llamadas de función en el acceso a un único valor de un registro de CPU. Esto puede convertirse en una terrible rendimiento de cerdos en un agradable y rápido programa.


Ocultar estado como datos privados en los objetos (encapsulación) tiene sus costos. Inline fue parte de C++ desde el principio con el fin de minimizar los costos de la abstracción. En aquel entonces, los compiladores fueron significativamente peores en la detección de buenos candidatos para inline (y rechazar las malas) que hoy en día, así que manualmente inline dio como resultado una considerable velocidad gainings.
Hoy en día los compiladores tienen la fama de ser mucho más inteligente de lo que se nos acerca en línea. Los compiladores son capaces funciones en línea de forma automática o no funciones en línea de los usuarios marcados como inline, aunque podría. Algunos dicen que las alineaciones se deben dejar para el compilador completamente y nos debería siquiera se moleste en marcado funciones como inline. Sin embargo, todavía tengo que ver a un exhaustivo estudio que muestra ya sea de forma manual de hacerlo es todavía vale la pena o no. Así que por el momento, voy a seguir haciendo a mí mismo, y dejar que el compilador anular que si piensa que puede hacerlo mejor.

5voto

kilotaras Puntos 1217

vamos

int sum(const int &a,const int &b)
{
     return a + b;
}
int a = sum(b,c);

es igual a

int a = b + c

No saltar - no sobrecarga

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X