c++ - resueltos - ¿Cómo determino el orden de enlace más rápido?
orden de enlace y longitud de enlace (4)
Tengo alrededor de 50 bibliotecas estáticas diferentes vinculadas en mi proyecto de c ++ y el enlace toma en promedio 70s.
Descubrí que el cambio con el orden de enlace de las bibliotecas cambia esta vez. Se espera que esto ocurra, supongo que si el enlazador no tiene que seguir buscando un conjunto de símbolos en toda la tabla de símbolos que ha construido hasta ese punto.
Supongo que podría usar "nm" para obtener un gráfico de dependencia entre las bibliotecas estáticas. Sin embargo, eso solo me daría un orden de enlace "correcto". ¿Cuáles serían los factores involucrados en obtener el orden de enlace más rápido?
Me da la sensación de que tendría algo que ver con el gráfico de dependencia mencionado al obtener un recorrido que intentaría minimizar una cantidad, pero realmente no estoy seguro de cuál.
Cualquier ayuda sería apreciada.
Principalmente estoy usando el compilador de inteligencia y también el compilador gcc de vez en cuando. Ambos parecen estar usando el enlazador GNU ld cuando lo miro con la parte superior. Espero que esto ayude...
Entonces, para aclarar un poco más sobre lo que trato de hacer, ya sé cómo obtener un pedido de 1 paso de un conjunto de bibliotecas estáticas. Yo mismo había escrito este guión, pero como sugiere la respuesta de Olaf a continuación, existen herramientas bien conocidas para hacerlo.
Mi pregunta es: ya tengo dos ordenamientos de enlaces de 1 paso, uno de los cuales se ejecuta en ~ 85s y el otro se ejecuta en ~ 70s. Claramente, todavía hay algo más de optimización que podemos hacer dentro de las órdenes de 1 pase.
Como alternativa, ¿por qué no intentar compilar sus bibliotecas a bibliotecas compartidas en lugar de bibliotecas estáticas?
Donde trabajo, un gran proyecto de tiempo de enlace fue de alrededor de 6 minutos, esto fue solo para 5 bibliotecas!
Mi solución era (para una versión de depuración) crear archivos .so alfabéticamente (libA.so, libB.so, etc.), por lo que cada enlace individual no era demasiado largo, y el enlace final era mucho más corto, porque todos los enlaces (parciales) había sido hecho previamente. La versión de lanzamiento fue construida a la vieja usanza porque había un "peligro" percibido con mi nuevo método.
Logré obtener un ciclo de compilación / enlace de 1 módulo de 6 minutos a 10 segundos usando este método.
En el pasado, el orden de los objetos en una biblioteca estática era importante. Puede ordenar los objetos de acuerdo con:
$ lorder * .o | tsort
Tal vez podría hacer lo mismo con sus principales objetos y bibliotecas, por ejemplo lorder main.o test.o libsome.a libthing.a | tsort
lorder main.o test.o libsome.a libthing.a | tsort
. Mira hombre lorder
Está hablando de un pedido de un solo paso basado en el orden de objetos y bibliotecas, pero si está buscando a través de una biblioteca estática no puede garantizar que nada en la biblioteca estática estará en un orden particular y, de hecho, solo puede controlar eso ordenando la biblioteca estática de cierta manera cuando lo haces.
Además, sin entender cómo el enlazador hace uso de la biblioteca estática (y | ies), las dos mejores suposiciones que podrían hacerse son:
- Crea una tabla hash de símbolos que hace referencia a los objetos que los proporcionan o necesitan; si se trata de una suposición precisa, entonces el mejor límite inferior que puede obtener en una biblioteca estática es el tiempo que lleva llenar una tabla hash y leer de ella.
- Lee ciegamente del archivo basado en el orden dado en el índice del archivo.
Como un intento de encontrar un límite inferior en su tiempo de enlace óptimo, intente vincular todo o un subconjunto de los objetos en el archivo (s) como un objeto reubicable; para el subconjunto, si es posible, identifique todos los objetos realmente vinculados en.
La página man para lorder
indica que puede obtener los mismos resultados con ar ts <archive>
... que imprimirá la lista ordenada por usted. La página man para ar
parece indicar que al ejecutar ar
con la bandera s
se almacenará automáticamente esa ordenación óptima en el índice del archivo.
Además, ten en cuenta que podría haber dependencias cíclicas, aunque si ya te has tsort
con la tsort
ya deberías haberlo tenido en cuenta.
Finalmente, los dejo con una última información. Lo que quiere es algo que pueda resolver un problema NP-completo. Buena suerte.
He estado ejecutando algunas pruebas de tiempo el último momento para una construcción en la que trabajo; ARFLAGS
bandera s
a mi ARFLAGS
para ver qué efecto tiene.
En general, parece haber aumentado mi tiempo de compilación, pero creo que hay una explicación lógica de por qué:
- La mayoría de los ejecutables / objetos compartidos no usan enlaces estáticos
- Está construyendo versiones PIC y no PIC de cada biblioteca estática
Si utilizáramos mucho más las bibliotecas estáticas, probablemente veríamos un beneficio al hacer esto.
Según la información que compara ld con oro , la velocidad de ld se ve afectada por el tamaño de la tabla de símbolos. A medida que la tabla de símbolos crece a partir del procesamiento de archivos de objetos, más lento se vuelve el paso del enlace. Por lo tanto, si tiene dos órdenes de enlace de 1 paso diferentes, la que coloca las bibliotecas con un número mayor de símbolos para corregir más adelante en ese orden debe vincularse más rápido. Debería poder modificar una clasificación topológica para incluir el conteo de símbolos en los criterios de ordenamiento.