2010-07-22 12 views

Respuesta

15

La palabra clave inline en realidad no hace que las funciones estén en línea. Cualquier compilador reciente va a tomar mejores decisiones con respecto a la creación que usted.

En el caso de una lambda corta, la función probablemente estará en línea.

Si está intentando usar la palabra clave inline con una lambda, la respuesta es no, no puede usar eso.

+3

Es trivialmente fácil encontrar contraejemplos al reclamo de que un compilador reciente tomará mejores decisiones sobre el revestimiento que una voluntad humana determinada. Todavía no soy un gurú de C cuando he tenido un código de velocidad crítica, etiquetar un método con una sugerencia en línea a menudo produce un ejecutable más rápido. Todo lo que uno tiene que hacer es medir el código. Aconsejaría a cualquiera a quien le hayan dicho que el compilador sabe mejor cómo configurar un banco de pruebas donde puedan cronometrar varias funciones con y sin pistas en línea para explorar cuándo se puede superar al compilador. – jackmott

+1

@jack Por supuesto. Pero necesita cosas como __declspec (forceinline) o __declspec (noinline) para hacer eso. Si hacer eso produce una mejora mensurable, 1. necesita más LTO/LTCG, 2. necesita más PGO o 3. errores de compilación. Los compiladores no hacen todo lo que las personas dicen que hacen todo el tiempo, pero inline es una de esas áreas en las que en general son realmente realmente buenos. –

9

Es posible que una expresión lambda esté en línea. Debajo del capó, una expresión lambda no es diferente de cualquier otro objeto de función.

Si una expresión lambda particular está en línea depende completamente del compilador y si decide si vale la pena subrayarla.

3

Si tiene un functor de estructura regular, el compilador casi seguramente lo alineará. Si tiene un lambda de estilo C++ 0x, el compilador casi seguramente lo alineará. Si está utilizando un boost :: lambda, entonces podría funcionar, dependiendo de cómo funcione el lambda debajo de las escenas. Versión corta: no puede garantizar que sea lineal o no, pero debe confiar en su compilador y, en caso de duda, facilite y simplifique la integración.

1

No he visto la salida de un lote de ninguna manera, pero hasta ahora todos los que he visto en la salida están en línea.

0

C++ 1x 'lambdas generará, bajo el capó, objetos de función normal. Esos pueden ser escritos por el compilador.

¿Alguna de las medidas que realizó sugiere que el compilador no las alineó en un lugar donde esto provoca una pérdida de rendimiento notable?

+1

Nitpick: ningún trabajo en C++ 1x ha comenzado todavía, y no es más que una conjetura de que incluso habrá un C++ 1x. El comité todavía está trabajando en C++ 0x, y no es probable que el título de trabajo cambie, simplemente porque no coincidirá con el título corto final del estándar. –

+0

@Christopher: No estoy de acuerdo. Es probable que el próximo estándar de C++ sea C++ 11, podría convertirse en C++ 12, es poco probable que se convierta en C++ 10 e imposible convertirse en C++ 09. Como el último (y solo el último) dígito es incierto, comúnmente es reemplazado por un 'x'. No se garantiza si tendrá lambdas (solo mire las consecuencias), pero es muy poco probable que el comité se conformaría con algo menos. – sbi

+0

La broma es que el 0x es hexadecimal ahora, ya que la mayoría de la gente continúa usando C++ 0x – ZachS

12

El compilador lo alineará si es posible. Por ejemplo, en g ++ 4.5 con -O2,

#include <vector> 
#include <algorithm> 

int main() { 
    std::vector<int> a(10); 
    for (int i = 0; i < 10; ++ i) a[i] = i; 

    asm ("Ltransform_begin: nop; nop; nop; nop; nop; nop; "); 
    std::transform(a.begin(), a.end(), a.begin(), [] (int x) { return 2*x; }); 
    asm ("Lforeach_begin: nop; nop; nop; nop; nop; nop; "); 
    std::for_each(a.begin(), a.end(), [] (int x) { printf("%d\n", x); }); 
    asm ("Lforeach_done: nop; nop; nop; nop; nop; nop; "); 

    return 0; 
} 

genera el conjunto que los y printf lambdas están completamente inline.

# 9 "x.cpp" 1 
    Ltransform_begin: nop; nop; nop; nop; nop; nop; 
# 0 "" 2 
    .align 4,0x90 
L13: 
    sall (%rax) 
    addq $4, %rax 
    cmpq %rax, %r12 
    jne L13 
# 13 "x.cpp" 1 
    Lforeach_begin: nop; nop; nop; nop; nop; nop; 
# 0 "" 2 
    .align 4,0x90 
L14: 
    movl (%rbx), %esi 
    leaq LC0(%rip), %rdi 
    xorl %eax, %eax 
LEHB1: 
    call _printf 
LEHE1: 
    addq $4, %rbx 
    cmpq %r12, %rbx 
    jne L14 
# 17 "x.cpp" 1 
    Lforeach_done: nop; nop; nop; nop; nop; nop; 
# 0 "" 2