2009-10-13 20 views
5

Tengo una biblioteca de C++ que genera un código mucho más grande que realmente esperaría para lo que está haciendo. De menos de 50K líneas de fuente, obtengo objetos compartidos que son casi 4 MB y archivos estáticos que presionan 9. Esto es problemático porque los binarios de la biblioteca son bastante grandes, y, lo que es peor, incluso las aplicaciones simples que se vinculan normalmente ganan de 500 a 1000 KB en el tamaño del código. Compilar la biblioteca con indicadores como -Os ayuda un poco, pero no mucho.¿Cuáles son algunas técnicas o herramientas para perfilar un tamaño de código excesivo en aplicaciones C/C++?

También experimenté con el comando -frepo de GCC (aunque toda la documentación que he visto sugiere que en Linux collect2 se fusionarán las plantillas duplicadas) y la creación de instancias explícitas de plantillas que parecían "probablemente" duplicadas mucho , pero sin efecto real en ninguno de los casos. Por supuesto que digo "probable" porque, como con cualquier tipo de perfil, las conjeturas ciegas como esta casi siempre son incorrectas.

¿Hay alguna herramienta que facilite el tamaño del código de perfil, o de alguna otra manera puedo averiguar qué ocupa tanto espacio, o, en general, cualquier otra cosa que deba probar? Algo que funcione bajo Linux sería ideal pero tomaré lo que pueda obtener.

Respuesta

7

Si quiere saber qué se pone en su ejecutable, pregunte sus herramientas. Active la opción ld del vinculador --print-map (o -M) para producir un archivo de mapa que muestre qué ha puesto en la memoria y dónde. Hacer esto para el ejemplo de enlace estático es probablemente más informativo.

Si no está invocando ld directamente, pero solo a través de la línea de comando gcc, puede pasar opciones específicas ld a ld desde la línea de comando gcc precediéndolas con -Wl,.

+0

No es '-W1', es' -Wl' –

+0

@FX - Gracias por detectar eso. Lo he arreglado –

1

Un método que es muy crudo pero muy rápido es ver el tamaño de los archivos de objeto. No todo el código de los archivos objeto se compilará en el binario final, por lo que puede haber algunos falsos positivos, pero puede dar una buena impresión de dónde estarán los puntos conflictivos. Una vez que haya encontrado los archivos de objetos más grandes, puede profundizar en ellos con herramientas como objdump y nm.

2

En Linux, el enlazador ciertamente fusiona varias instancias de plantilla.

Asegúrese de no estar midiendo binarios de depuración (la información de depuración podría ocupar más del 75% del tamaño binario final).

Una técnica para reducir el tamaño binario final es compilar con -ffunction-sections y -fdata-sections, luego vincular con -Wl,--gc-sections.

reducción aún mayor (que hemos visto el 25%) puede ser posible si utiliza versión de desarrollo de [gold][1] (el nuevo ELF solo enlazador, parte de binutils), y el enlace con -Wl,--icf

Otra técnica útil es reduciendo el conjunto de símbolos que son "exportados" por sus bibliotecas compartidas (todo se exporta por defecto), ya sea a través de __attribute__((visibility(...))), o mediante el uso de secuencia de comandos del enlazador. Detalles here (ver "Control de exportación").

Cuestiones relacionadas