7

La documentación de __assume dice "El uso más común de __assume es con el caso predeterminado de una instrucción switch, como se muestra en el siguiente ejemplo".¿Algún ejemplo de __assume que lleva a un código más rápido que no sea "no default" en el switch?

  • ¿Hay algún otro caso donde __assume puede conducir a un código más eficiente (o incluso diferente)?
  • Cuando está dentro de if/else, ¿el compilador "asume" automáticamente lo que ya se conoce debido a la condición?

No he podido encontrar ningún ejemplo no trivial que muestre alguno de los anteriores, espero que alguien más pueda hacerlo.

Respuesta

7

considere el siguiente código, compilado con el interruptor /Ox:

if (1) { 
    printf("live code\n"); 
} else { 
    printf("dead code\n"); 
} 

El optimizador optimizar la distancia else. Consideremos ahora:

int x = 1; 
if (x == 1) { 
    printf("live code\n"); 
} else { 
    printf("dead code\n"); 
} 

El optimizador volverá a optimizar la distancia else. También tienen en cuenta:

int x = 1; 
__assume(x != 1); 
if (x == 1) { 
    printf("live code\n"); 
} else { 
    printf("dead code\n"); 
} 

El optimizador optimizar la distancia if este tiempo - de manera incorrecta.

Para probar, construir un programa de prueba en modo de lanzamiento (con los /Ox y /Zi opciones) y observar el ensamblaje generado (Alt+8 en Visual Studio.)

Consideremos ahora el if/else condición anterior se está probando en un inline método. En ciertos contextos, el programador puede saber que el método en línea se llama con un valor particular y que el optimizador puede no haberse dado cuenta de este hecho. El uso de __assume en el nivel de la persona que llama de la manera ilustrada anteriormente, justo antes de que se llame al método inline, puede ayudar teóricamente al optimizador.

De Optimization Best Practices:

__assume ha sido en Visual C++ para varias versiones, pero se ha convertido mucho más útil en Visual C++ 2005. Con __assume, un desarrollador puede decir el compilador para hacer supuestos sobre el valor de alguna variable.

Por ejemplo __assume (a < 5); le dice al optimizador que en esa línea de código la variable a es menor que 5. De nuevo esto es una promesa para el compilador. Si a es actualmente 6 en este punto en el programa , entonces el comportamiento del programa después de que el compilador haya optimizado puede no ser lo que esperaría . __assume es más útil antes de para cambiar declaraciones y/o expresiones condicionales.

Existen algunas limitaciones para __assume. Primero, como __restrict, es solo una sugerencia, por lo que el compilador puede ignorarlo.Además, __assume actualmente solo funciona con desigualdades de constantes. Es no propaga las desigualdades simbólicas, por ejemplo, asume (un < b).

+0

Dado que __assume está documentado como una sugerencia de compilación, creo que el comportamiento que muestra (optimizar la cláusula else) es un error. ¿Pudiste ver eso con un solo compilador y lo has visto con las versiones más nuevas de msvc? – Garen

+0

@Garen, el comportamiento que se muestra es coherente con la documentación, ¿por qué __supongo que es un error? Siéntete libre de probarlo con tu sabor favorito de MSVC, IIRC, el anterior fue probado con VC2010. – vladr

Cuestiones relacionadas