2012-11-13 7 views
38

Ho circa 50 diverse librerie statiche collegate al mio progetto C++ e il collegamento richiede in media 70 secondi.Come determinare l'ordine di collegamento più veloce?

Ho scoperto che spostarsi con l'ordine di collegamento delle librerie cambia questa volta. Questo è previsto, suppongo che se il linker non debba continuare a cercare una serie di simboli lungo l'intera tabella dei simboli che ha costruito fino a quel punto.

Suppongo che potrei usare "nm" per ottenere un grafico di dipendenza tra le librerie statiche. Tuttavia, questo mi darebbe solo un ordine di link "corretto". Quali sarebbero i fattori coinvolti nell'ottenere l'ordine di collegamento più veloce?

Ho la sensazione che avrebbe avuto qualcosa a che fare con il grafico delle dipendenze sopra menzionato ottenendo un attraversamento che avrebbe cercato di minimizzare una certa quantità ma non sono davvero sicuro di quale.

Qualsiasi aiuto sarebbe apprezzato.

Principalmente uso il compilatore intel e anche il compilatore gcc di tanto in tanto. Entrambi sembrano usare il linker GNU ld quando lo controllo con top. Spero che questo aiuti ...

Quindi, per chiarire un po 'di più su quello che sto cercando di chiedere, so già come ottenere un ordinamento a 1 passaggio da un set di librerie statiche. Avevo scritto questo script da solo ma come suggerisce la risposta di Olaf qui sotto, ci sono strumenti ben noti per farlo.

La mia domanda è, ho già due ordini di collegamento a 1 passaggio uno dei quali viene eseguito in ~ 85s e l'altro viene eseguito in ~ 70s. Quindi, chiaramente, c'è ancora un po 'di ottimizzazione che possiamo fare con gli ordini in un solo passaggio.

+1

Probabilmente la lista di simboli/simboli non risolti, ma è più una sensazione che una conoscenza. Sidenote: tu ** devi ** indicare il linker a cui sei interessato, poiché i diversi linker hanno un comportamento completamente diverso (ibm itera più volte nell'elenco delle librerie fino a quando non risolve tutto o c'è progresso, ad esempio) –

+0

Ho fatto lo stato Sto usando la suite del compilatore intel in modo che possa essere ld (almeno sembra che stia eseguendo ld quando controllo con top). Ora lavoro anche con la suite di compilatori gcc, quindi anche ld. – owagh

+0

Una semplice idea: scrivi uno script per permutare tutti gli ordini possibili delle librerie e misurare il tempo di collegamento in modo programmatico. –

risposta

6

In passato, l'ordine degli oggetti in una libreria statica era importante. È possibile ordinare gli oggetti di conseguenza con:

$ lorder * .o | tsort

Forse potresti fare lo stesso con i tuoi oggetti e le tue librerie principali, ad es. lorder main.o test.o libsome.a libthing.a | tsort. Guarda man lorder

+0

Sembra un'utilità interessante ma non l'ho installato. Puoi indicarmi il pacchetto che lo ha? – owagh

+0

Sono su Debian/Ubuntu. 'dpkg -S lorder tsort' mi dà' bsdmainutils' e 'coreutils'. –

+0

Grazie! Inoltre, il lorder sembra dare solo un grafico di ordine parziale quindi suppongo che sia solo equivalente al mio script che ha generato queste informazioni. Questo ci darebbe solo un ordine totale "corretto" ma non necessariamente quello che porterebbe all'ordine totale più veloce. – owagh

3

In base alle informazioni comparing ld to gold, la velocità di ld dipende dalla grandezza della tabella dei simboli. Man mano che la tabella dei simboli cresce dall'elaborare i file oggetto, tanto più lento diventa il passaggio del collegamento. Quindi, se hai due ordini di collegamento a 1 passaggio diversi, quello che mette le librerie con un numero maggiore di simboli da correggere in un secondo momento in quell'ordine dovrebbe collegarsi più velocemente. Dovresti essere in grado di modificare un ordinamento topologico per includere il conteggio dei simboli nei criteri di ordinamento.

8

In alternativa, perché non provare a compilare le librerie su librerie condivise anziché su librerie statiche?

Dove lavoro, un tempo di collegamento di grandi progetti era di circa 6 minuti, questo era per solo 5 librerie!

La mia soluzione era (per una versione di debug), creare file .so alfabeticamente (libA.so, libB.so ecc.) Quindi ogni collegamento individuale non era troppo lungo e il collegamento finale era molto più breve, perché tutto il il collegamento (parziale) era stato fatto in precedenza. La versione di rilascio è stata costruita alla vecchia maniera perché c'era un "pericolo" percepito con il mio nuovo metodo.

Sono riuscito a ottenere un ciclo di compilazione/collegamento di 1 modulo da 6 minuti a 10 secondi utilizzando questo metodo.

3

Si sta parlando di un ordinamento a un passaggio in base all'ordine degli oggetti e delle librerie, ma se si ricerca attraverso una libreria statica non si può garantire che nulla nella libreria statica sarà in un ordine particolare e di fatto può controllarlo solo ordinando la libreria statica in un certo modo quando lo si usa.

Inoltre, senza capire come il linker si avvale della coll statica (y | ies), i due migliori ipotesi che potrebbe essere fatto è:

  1. Si crea una tabella hash di simboli che fa riferimento all'oggetto (s) che forniscono o hanno bisogno di loro; se si tratta di un'assunzione accurata, il miglior limite inferiore che è possibile ottenere su una libreria statica è il tempo necessario per compilare una tabella di hash simile e leggere da essa.
  2. Legge ciecamente dall'archivio in base all'ordine indicato nell'indice dell'archivio.

Come tentativo di trovare un limite inferiore sul tempo di collegamento ottimale, provare a collegare tutto o un sottoinsieme degli oggetti negli archivi come oggetto rilocabile; per il sottoinsieme, se possibile, identificare tutti gli oggetti effettivamente collegati.

La pagina man per lorder indica che è possibile ottenere gli stessi risultati con ar ts <archive> ... che stamperà l'elenco ordinato per voi. La pagina man per ar sembra indicare che l'esecuzione di ar con il flag s memorizzerà automaticamente l'ordinamento ottimale nell'indice dell'archivio.

Inoltre, sappi che potrebbero esserci delle dipendenze cicliche, anche se hai già messo a soqquadro con tsort dovresti esserne già stati informati.

Infine, vi lascio con un'ultima informazione. Quello che vuoi è qualcosa che possa risolvere un problema NP-completo. In bocca al lupo.


Ho eseguito alcuni test di temporizzazione negli ultimi tempi per una build su cui lavoro; Ho aggiunto la bandiera s al mio ARFLAGS per vedere quale effetto ha.

Nel complesso, sembra che abbia aumentato il mio tempo di costruzione, ma credo che ci sia una spiegazione logica del perché:

  • La maggior parte degli eseguibili/oggetti condivisi non usano statica che collega
  • E 'la costruzione di PIC e non - Versioni PIC di ogni libreria statica

Se stessimo facendo un uso molto più pesante delle librerie statiche, probabilmente vedremmo un vantaggio nel farlo.

+0

Non ho mai visitato questa domanda da molto tempo ... Ad ogni modo, cosa intendi per "la maggior parte degli eseguibili non usa il collegamento statico". Ti riferisci in particolare ai tuoi dirigenti? – owagh

+0

Sì; la maggior parte degli eseguibili nella nostra build si collegano esclusivamente alle librerie dinamiche. –