c++ function-pointers function-object inlining

c++ - ¿Los functores son realmente más rápidos que los punteros a las funciones?



function-pointers function-object (3)

Según Scott Meyers, un área donde C ++ brilla sobre C es que los objetos de función son más rápidos que los punteros de función. Él dice que esto se debe a que los objetos de función están en línea, lo que aumenta la velocidad.

Tengo dos preguntas sobre esto:

  1. ¿Cómo podemos verificar que los objetos de función estén, de hecho, en línea? ¿Podemos verificar esto en la práctica?

  2. ¿La alineación de los objetos de función depende del compilador que usamos, o todos los compiladores se comportan así?


  1. ¿Cómo podemos verificar que los objetos de función estén de hecho en línea? ¿Podemos verificar esto en la práctica?

Claro, inspeccione el código de ensamblador finalmente emitido.

  1. Los objetos de función de línea dependen del compilador que usamos, o ¿todos los compiladores se comportan así?

Depende en gran medida de la implementación del compilador y el nivel de optimización utilizado.
Entonces no, no hay garantía de que compiladores particulares (enlazadores) se comporten así.

Sin embargo, las llamadas a través de punteros de función no se pueden alinear.

Según él, los objetos de función están en línea, por lo que hay un aumento en la velocidad.

OMI "los objetos de función están en línea" deberían leerse mejor (o escucharse, no sé de dónde es esa cita):

los objetos de función pueden estar en línea mientras que las llamadas a través de punteros de función no.


Los estándares C ++ y C dejan mucha libertad a los compiladores. Los compiladores son libres de contar hasta mil millones entre cada instrucción, o solo lo hacen si un número entero tiene un valor primo.

Los compiladores "reales" decentes no hacen esto. Este es un problema de calidad de implementación.

Incluir objetos de función en algo como std::sort es algo que todo compilador real hace. Es extremadamente fácil detectar lo que necesita ser insertado en esos casos, porque la información de tipo lleva consigo el código que necesita ser insertado.

Hacerlo con un puntero de función es más difícil. Hacerlo con un puntero de función donde todo se ha convertido en punteros void* o char* es aún más difícil.

El efecto de esto es que, en la práctica, una llamada de estilo C a qsort frente a una llamada de estilo C ++ a std::sort puede resultar en una gran ventaja para std::sort .

qsort es aproximadamente 2 qsort más lento que std::sort , como se muestra here , en una situación ridículamente simple de ordenar enteros dispuestos aleatoriamente.

Inspeccionar la salida del código de ensamblaje real es principalmente un detalle, y es mucho trabajo por poco retorno. Tomar ejemplos concretos del mundo real te da una idea de cuán grande es realmente el impacto.

Los 3 de clang, gcc y MSVC fueron capaces de hacer que std::sort sea ​​significativamente más rápido que su qsort . Y como esta es una optimización fácil, mientras que optimizar los punteros de función en llamadas en línea no lo es, esperaría que los compiladores menos importantes no fueran mejores que esto en qsort .


Sí, los objetos de función pueden conducir a un código más rápido. Pero la única forma de garantizar eso es hacer una referencia.

  1. La documentation dice: "Es posible que GCC aún no pueda alinear una función por muchas razones; la opción -Winline se puede usar para determinar si una función no se ha incorporado y por qué no " .

  2. Por supuesto, dependerá del compilador, la versión, los indicadores, etc. En ocasiones, la alineación puede ser contraproducente (expansión de código, etc.), por lo que cada compilador tiene su propio conjunto de reglas para decidir si una función debe estar incorporada. Por cierto, la palabra clave en inline es solo una pista, y algunas bibliotecas como eigen tienen dificultades para imponer la inline.