2011-12-12 10 views
5

¿Hay alguna manera de indicarle al compilador que usted sabe que el valor de una variable en particular debe estar dentro de un rango particular en un cierto punto del código, para ayudar al compilador a optimizar? Estoy escribiendo una biblioteca que hace posible conocer el rango de algunas variables en tiempo de compilación, y sería ingenioso si de alguna manera pudiera comunicar esta información al compilador para que el compilador pueda usarla para la optimización. Me gustaría agregar soporte para cualquier compilador en el que funcione, incluso si no se puede hacer que funcione para todos ellos (parece el tipo de cosa que algunos compiladores podrían tener como extensión, pero no lo he hecho). encontrado alguno). Sé que podría escribir algo como esto:¿Cómo comunicar información de rango al compilador de C++?

if(x < COMPILE_TIME_MIN or x > COMPILE_TIME_MAX) 
    return; 
// compiler will assume for code below that x is in range COMPILE_TIME_MIN..COMPILE_TIME_MAX 

Pero eso es un control del tiempo de ejecución. Tal vez haya algún truco para que el compilador haga una suposición sobre el rango sin dicho control?

+2

¿Tiene alguna idea sobre qué tipo de optimización ayudaría? –

+0

Si usa plantillas, puede hacer un tiempo de compilación comprobando si se conoce toda su información en tiempo de compilación. –

+0

Está utilizando la frase "el compilador", pero nunca nos dice cuál. Presumiblemente, te refieres a alguna versión de g ++ o Visual C++, pero eso no está claro. El estándar no aborda la optimización en general, por lo que cualquier cosa que pueda hacer aquí es específica de la implementación. –

Respuesta

6

Cualquiera de estos "consejos" sería específico del compilador.

Como un ejemplo, Visual C++ le permite proporcionar tal sugerencia usando the __assume intrinsic.

(Otros compiladores pueden también proporcionar tales características intrínsecas, pero no estoy lo suficientemente familiarizado con otros compiladores de proporcionar cualquier información adicional. Consulte la documentación del compilador si está interesado.)

+3

Desde mi propio Google, gcc 4.5 y posteriores pueden pasar esta información junto con la misma sintaxis usando '#define __assume (cond) do {if (! (Cond)) __builtin_unreachable(); } while (0) ' –

+0

@DrewDormann Interesante. Creo que sería mejor definir una sola macro '#define ASSUME_THIS_THING (x) ...' que se expande a '__assume (x)' en Visual C++ y su fragmento en gcc. Lo mejor es no definir su propia macro con un nombre reservado por el compilador (como '__assume'). –

+0

Guau, eso es increíble. James, ¿quieres unir la información de Drew en tu respuesta? Entonces marcaré como aceptado. –

3

No es estándar, pero con gcc, llega un comando llamado __builtin_expect, con macros definidas como likely y unlikely que sirven para su propósito. Véase here por ejemplo, que habla sobre su uso en kernel-space, pero __builtin_expect es una extensión de gcc y también se puede usar en el espacio de usuario (ver this question), incluso si likely y unlikely no están definidos.

+0

Hay un error tipográfico en el comentario anterior: debe ser '__builtin_expect'. GCC solo usa la expectativa como una sugerencia: no evitará los casos en los que no se cumple la expectativa. –

+0

@MattG, sí, no sé cómo había escrito 'buildtin'! – Shahbaz

0

No conozco ninguna técnica de compilación de C++ que aproveche esta información, pero conozco varias técnicas de análisis estático que sí lo hacen; la forma común de "decir" algo a esas herramientas sería a través de assert s, por ejemplo:

assert(x > COMPILE_TIME_MIN); 
assert(x < COMPILE_TIME_MAX); 

Pero por lo general esas herramientas también serían capaces de analizar las cosas tales como "si las condiciones" por sí mismos, por lo no hay una necesidad especial de hacerlo.

Además, si el rango es muy pequeño, también puede representarlo en una variable de menor tamaño, p. Ej. usando un short o char - y agregando COMPILE_TIME_MIN. Eso puede ayudar a tales herramientas, aunque no sé sobre la compilación en sí.

Y, por último, como en todos los enfoques de optimización, recomiendo primero crear un perfil de su código para ver si esto realmente podría ser un cuello de botella. Además, tenga en cuenta que los compiladores están diseñados para optimizar el código "normal", la optimización de la mano podría ayudar, simplemente hágalo con cuidado.

Cuestiones relacionadas