Domanda

Sul dispositivo incorporato su cui sto lavorando, il tempo di avvio è un problema importante. L'intera applicazione è composta da diversi eseguibili che utilizzano un set di librerie. Poiché lo spazio nella memoria FLASH è limitato, vorremmo utilizzare le librerie condivise.

L'applicazione funziona normalmente quando compilata e collegata con librerie condivise e la quantità di memoria FLASH è ridotta come previsto. La differenza con la versione collegata alle librerie statiche è che il tempo di avvio dell'applicazione è di circa 20 secondi più lungo e non ho idea del perché.

L'applicazione funziona su una CPU ARM9 a 180 MHz con sistema operativo Linux 2.6.17, 16 MB FLASH (file system JFFS) e 32 MB di RAM.

È stato utile?

Soluzione

Perché le librerie condivise devono essere collegate in fase di runtime, di solito tramite dlopen () o qualcosa di simile. Non esiste un passaggio simile per le librerie statiche.

Modifica: qualche dettaglio in più. dlopen deve eseguire le seguenti attività.

  • Trova la libreria condivisa
  • Caricalo in memoria
  • Carica ricorsivamente tutte le dipendenze (e le loro dipendenze ....)
  • Risolvi tutti i simboli

Questo richiede un sacco di operazioni di I / O per eseguire.

In un programma collegato staticamente tutto quanto sopra è fatto in fase di compilazione, non in fase di esecuzione. Pertanto è molto più veloce caricare un programma collegato staticamente.

Nel tuo caso, la differenza è esagerata dall'hardware relativamente lento su cui deve essere eseguito il codice.

Altri suggerimenti

Questo è un ottimo esempio del classico compromesso tra velocità e spazio.

Puoi collegare staticamente tutti i tuoi eseguibili in modo che siano più veloci ma che occuperanno più spazio

o

Puoi avere librerie condivise che richiedono meno spazio ma anche più tempo per il caricamento.

Quindi decidi cosa vuoi sacrificare.

Esistono molti fattori per questa differenza (sistema operativo, compilatore ecc.) ma è possibile trovare un buon elenco di motivi qui . Le librerie sostanzialmente condivise sono state create per motivi di spazio e gran parte della "magia" coinvolto per farli funzionare prende un colpo di prestazione.

(Come nota storica, il navigatore Netscape originale su Linux / Unix era un grosso eseguibile collegato staticamente).

Questo può aiutare gli altri con problemi simili:

Il motivo per cui l'avvio ha richiesto così tanto tempo nel mio caso è che l'impostazione predefinita di GCC è quella di esportare tutti i simboli all'interno di una libreria. Un grande miglioramento è quello di impostare un'impostazione del compilatore " -fvisibility = hidden " ;.

Tutti i simboli che la lib deve esportare devono essere aumentati con la dichiarazione

__attribute__ ((visibilità (" default ")))

vedi gcc wiki
e il bellissimo articolo come scrivere librerie condivise

Ok, ho imparato ora che l'uso delle librerie condivise ha i suoi svantaggi per quanto riguarda la velocità. Ho trovato questo articolo su collegamento dinamico e caricamento illuminante. Il processo di caricamento sembra essere molto più lungo di quanto mi aspettassi.

Interessante .. in genere il tempo di caricamento di una libreria condivisa è impercettibile da un'app fat che è staticamente collegata. Quindi posso solo supporre che il sistema sia molto lento nel caricare una libreria dalla memoria flash, o che la libreria che viene caricata sia in qualche modo controllata (ad es. Le app .NET eseguono un checksum per tutte le dll caricate, riducendo notevolmente i tempi di avvio in alcuni casi). È possibile che le librerie condivise vengano caricate secondo necessità e successivamente scaricate, il che potrebbe indicare un problema di configurazione.

Quindi, scusami non posso fare a meno di dire perché, ma penso che sia un problema con il tuo dispositivo / sistema operativo ARM. Hai provato a strumentare il codice di avvio o a collegarti staticamente con 1 delle librerie più comunemente usate per vedere se ciò fa una grande differenza. Metti anche le librerie condivise nella stessa directory dell'app per ridurre il tempo necessario per cercare la libreria in FS.

Un'opzione che mi sembra ovvia, è quella di collegare staticamente tutti i programmi in un unico binario. In questo modo continuerai a condividere più codice possibile (probabilmente più di prima), ma eviterai anche il sovraccarico del linker dinamico E risparmierai lo spazio di avere il linker dinamico sul sistema.

È abbastanza facile combinare più eseguibili nello stesso, di solito basta esaminare argv e decidere quale routine chiamare in base a quello.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top