2010-10-04 13 views
6

duplicación de código is usually bad y, a menudo, bastante fácil de detectar. Supongo que los compiladores podrían detectarlo automáticamente en los casos más fáciles: ya analizan el texto y obtienen la representación intermedia que analizan de varias maneras: detectan patrones sospechosos como variables no inicializadas, optimizan el código emitido, etc. Supongo que a menudo podrían detectar duplicados funcionales código de esta manera también y cuenta al emitir código de máquina.¿Pueden los compiladores de C++ eliminar automáticamente el código duplicado?

¿Hay compiladores de C++ que pueden detectar código duplicado y sólo emitir el código máquina correspondiente una vez en lugar de para cada duplicado en el texto original?

+1

compilador del hombre vago? – Stephen

+1

No creo que sea una alta prioridad para los implementadores de optimizadores, ya que este tipo de código duplicado debe capturarse en el nivel de revisión del administrador/código del equipo. O más bien, el nivel de "buenas prácticas" ... – DevSolar

+0

@Stephen: Sí.Ya hemos llegado al punto en el que el compilador emite un código lo suficientemente eficiente como para no importarle las microoptimizaciones. – sharptooth

Respuesta

9

Algunos lo hacen, otros no.

Desde la página de la optimización LLVM: -mergefunc (MergeFunctions pass, how it works)

Las funciones están separadas en pequeños bloques en la Representación Intermedia LLVM, este paso de optimización trata de combinar bloques similares. Sin embargo, no está garantizado el éxito.

Encontrarás un montón de otras optimizaciones en esta página, a pesar de que algunos de ellos pueden aparecer críptica a primera vista.

Yo añadiría una nota sin embargo, que duplican código no es tan malo para el compilador/ejecutable, es malo desde el punto de vista del mantenimiento, y no hay nada que un compilador puede hacer al respecto.

+0

, pensaría que incluso si tiene éxito, no está garantizado para mejorar la velocidad. por supuesto, algunas personas necesitan optimizar el espacio de todos modos +1 –

+0

Interesante. No sé lo que quieren decir con "invalidable", pero generalmente no se puede hacer esto con las funciones C, ya que la igualdad se define sobre los punteros de función. – Potatoswatter

+0

@jk: Estoy de acuerdo en que la velocidad no se puede mejorar, creo que esto va en contra de la optimización de desenrollado del bucle tradicional. Sin embargo, puede con el marco LLVM especificar en qué orden desea aplicar optimizaciones, por lo que podría tener los dos. No precisan si se aplica un tipo de heurística (¿depende del tamaño del código?). Por un lado, incurre en un salto a otra ubicación de memoria, en el otro, menos código es más probable que esté en el caché ... así que supongo que, una vez más, solo necesitas medir para tu pequeña pieza de código :) –

8

Creo que la pregunta hace la suposición falsa de que los compiladores siempre querrán eliminar la duplicación de código. la duplicación de código es malo para facilitar la lectura/mantenimiento del código fuente no necesarily rendimiento del código compilado, en efecto, uno podría considerar como un compilador loop unrolling añadiendo código duplicado para aumentar la velocidad. El código compilado no necesita seguir los mismos principios que el código fuente y generalmente no lo hace, ya que no es para la lectura de la máquina ni para los humanos.

general, los compiladores están ocupados compilando no transformar el código fuente, de los entornos de desarrollo de cursos pueden permitir tanto.

+2

El código de fusión reduce el tamaño de la biblioteca producida/ejecutable, por lo que también puede acelerar la ejecución. Sin embargo, estoy de acuerdo con que esto entraría en conflicto con el desenrollado del bucle. –

+3

como con la mayoría de las cosas hay una compensación, pero en el supuesto de que el compilador siempre debe tratar de eliminar la duplicación es falso –

+2

No veo dónde esta pregunta hace tal suposición en absoluto. Se pregunta si algún compilador lo hace, no si es una buena idea, ni si los compiladores que * pueden * hacerlo siempre * lo harán *. –

1

Visual C++ lo hace si especifica 'minimizar el tamaño del código' (/ O1). La función proporcionada se describe en los documentos para /Og, que está en desuso en favor de opciones catch-all más simples para favorecer el tamaño o favorecer la velocidad (/ O2).

3

Según mi conocimiento, la eliminación del código no suele ocurrir en todas las funciones. Entonces, si escribes una pieza duplicada de código en dos funciones diferentes, hay muy pocas posibilidades (casi ninguna) de que esa pieza de código sea eliminada.

Existen algunas optimizaciones como return value optimization, function inlining que pueden ocurrir en todas las funciones. Sin embargo, la mayor parte de la optimización se realiza dentro de la función en sí misma. Esto no suele hacerse en el nivel de lenguaje superior, con esto quiero decir que el compilador no mirará el código C++ y comenzará a optimizarlo. Los compiladores en su mayoría tienen una representación intermedia, entre el lenguaje de alto nivel (C++) y el lenguaje de máquina. Esta representación intermediaria (IR) es algo similar al lenguaje de máquina, pero no es exactamente el lenguaje de máquina del sistema en el que se compila el código. Consulte la página wiki http://en.wikipedia.org/wiki/Compiler_optimization, enumera algunas de esas optimizaciones

Cuestiones relacionadas