Optimization

Originariamente di Gerard Beekmans gerard@linuxfromscratch.org Originariamente di Thomas -Balu-Walter tw@itreff.de Originariamente di Eric Olinger eric@supertux.com optimization2.txt

DESCRIZIONE:

Questo hint si prefigge essere una guida su come utilizzare o non utilizzare le routine di ottimizzazione della compilazione.

PREREQUISITI:

Nessuno

HINT:

L'origine di questo testo è la versione 2.4.3 del libro - Capitolo 6. E' stato modificato in parte per creare questo hint.
La maggior parte dei programmi e librerie di default sono compilati con livello di ottimizzazione 2 (opzioni gcc -g e -O2) e sono compilati per una specifica CPU. Sulle piattaforme Intel il software è compilato per processori i386 per default. Se non si vuole eseguire il software su altre macchine diverse dalla propria, si potrebbe voler modificare le opzioni di default del compilatore in modo che sia compilato con un livello di ottimizzazione superiore, e sia generato codice per la propria specifica architettura.
Ci sono alcuni modi per modificare le opzioni di default di compilazione. Un modo è di editare ogni file Makefile che si trova in un pacchetto, cercare le variabili CFLAGS e CXXFLAGS (un pacchetto ben progettato utilizza la variabile CFLAGS per definire le opzioni del compilatore gcc e CXXFLAGS per definire le opzioni del compilatore g++) e modificare i loro valori. Pacchetti tipo binutils, gcc, glibc e altri hanno molti file Makefile in molte sottodirectory, perciò occorrerebbe molto tempo per farlo. Invece c'è un modo più facile per farlo: creare le variabili d'ambiente CFLAGS e CXXFLAGS. La maggior parte degli script configure leggono le variabili CFLAGS e CXXFLAGS e le usano nei file Makefile. Alcuni pacchetti non seguono questa convenzione così da richiedere di essere editati manualmente. Per impostare queste variabili si possono eseguire i seguenti comandi in bash (o aggiungerli nel proprio .bashrc se si vuole che siano sempre disponibili):

export CFLAGS="-O3 -march=<architettura>" &&
CXXFLAGS=$CFLAGS

Questa è un'impostazione minima delle ottimizzazioni che ne assicurano il funzionamento su quasi tutte le piattaforme. L'opzione march permetterà la compilazione dei binari con le specifiche istruzioni per la CPU specificata. Questo significa che non è possibile copiare ed eseguire un binario in una CPU di classe più bassa. Funzionerebbe o in modo inaffidabile o per nulla (dando errori tipo “Illegal Instruction, core dumped”). Bisogna leggere la pagina d'informazioni di GCC per trovare i flag per la maggior ottimizzazione possibile. Nella suddetta variabile d'ambiente si deve sostituire <architettura> con l'appropriato identificativo di CPU così come i586, i686, powerpc e altro. Si suggerisce di dare uno sguardo al manuale gcc a http://gcc.gnu.org/onlinedocs/gcc_toc.html “Hardware Models and Configurations”.

/*
 * Ed. nota
 * "Reboant" rimosse una nota su come utilizzare -Os (ottimizzazione per 
 la dimensione) dava incredibilmente buoni risultati. Così che se si 
 desiderano binari di piccole dimensioni piuttosto che tempi di esecuzione 
 veloci, occorre darci uno sguardo.
*/

Ricordarsi che se si trova un pacchetto che non compila e dà errori del tipo “segmentation fault, core dumped” molto probabilmente si ha a che fare con queste ottimizzazioni della compilazione. Provare ad abbassare il livello di ottimizzazione modificandolo da -O3 a -O2. Se ciò non funziona provare -O o toglierlo del tutto. Provare anche a cambiare la variabile -march. I compilatori sono sensibili anche a hardware particolare. La memoria difettosa può causare problemi di compilazione quando si utilizza un alto livello di ottimizzazione, tipo l'impostazione -O3. Il fatto che un computer non abbia alcun problema compilando ogni cosa con -O3 non significa che un'altro non debba non averne. Un altro problema può essere la versione delle Binutils che è installata sul proprio sistema la quale spesso causa problemi di compilazione in Glibc (maggiormente riscontrabile in RedHat perché RedHat spesso utilizza software beta i quali spesso non sono molto stabili).
“RedHat ama essere all'avanguardia, ma lascia all'utente la scelta su dove esserlo”
(citazione da un anonimo sulla mailinglist lfs-discuss).

DEFINIZIONI PER I FLAG:

Per ulteriori informazioni sui flag di ottimizzazione della compilazione vedere la pagina del comando GCC nella documentazione Online di GCC 3.3.1 presso:
http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Optimize-Options.html#Optimize%20Options
http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/i386-and-x86-64-Options.html#i386%20and%20x86-64%20Options

-s
      Un'opzione del linker che rimuove tutta la tabella dei simboli e 
      il trasferimento delle informazioni dai binari.

-O3
      Questo flag imposta il livello di ottimizzazione per i binari.
              3	Livello più alto, viene generato codice specifico per
                      l'architettura della macchina.
 		        Auto-magicamente aggiunge i flag -finline-functions e
		-frename-registers.
              2       La maggior parte dei file Make lo hanno impostato 
                      come Default, esegue tutte le ottimizzazioni 
                      supportate che non comprendono il bilanciamento 
                      dimensione-velocità. Aggiunge auto-magicamente il 
                      flag -fforce-mem.
              1  	Vengono eseguite ottimizzazioni minimali. E' il 
                      default per il compilatore se non viene passato 
                      nessun valore.
              0       Non ottimizza.
              s       Come lo O2 ma esegue ottimizzazioni aggiuntive 
                      per la dimensione.

-fomit-frame-pointer 
      Dice al compilatore di non memorizzare il frame-pointer in un 
      registro per le funzioni che non ne hanno bisogno. Questo evita 
      alle istruzioni di salvare, impostare e ripristinare i frame-pointer; 
      inoltre rende disponibile un extra registro in molte funzioni. 
      Rende altresì impossibile il debug su alcune macchine.

-march=pentium3
      Definisce il set di istruzioni da utilizzare durante la compilazione.
      -mpcu è sottointeso sia uguale a -march quando è utilizzato soltanto -march.
              i386                    Processori Intel 386
              i486                    Processori Intel/AMD 486
              pentium                 Processori Intel Pentium
              pentiumpro      	Processori Intel Pentium Pro
	pentium2		Processori Intel PentiumII/Celeron
	pentium3		Processori Intel PentiumIII/Celeron
              pentium4                Processori Intel Pentium 4/Celeron
              k6                      Processori AMD K6
	k6-2			Processori AMD K6-2
	K6-3			Processori AMD K6-3
              athlon          	Processori AMD Athlon/Duron
	athlon-tbird		Processori AMD Athlon Thunderbird
	athlon-4		Processori AMD Athlon Version 4
	athlon-xp		Processori AMD Athlon XP
	athlon-mp		Processori AMD Athlon MP
	winchip-c6		Processori Winchip C6
	winchip2		Processori Winchip 2
	c3			Processori VIA C3 Cyrix

-mmmx
-msse
-msse2
-m3dnow
Questi switch abilitano o disabilitano l'uso di funzioni embedded
      che permettono l'accesso diretto alle estensioni MMX, SSE e 3Dnow 
      del set di istruzioni .

LINK PER L'OTTIMIZZAZIONE:

Flag sicuri per gentoo-1.4 http://www.freehackers.org/gentoo/gccflags/flag_gcc3.html
Sicurezza & Ottimizzazione in Linux: Soluzione definitiva v2.0 http://www.openna.com/products/books/sol/solus.php

ESPERIENZE PERSONALI:

Ho stato provato a utilizzare tutti i livelli di ottimizzazione, ma, con disappunto, i risultati sono variati da pacchetto a pacchetto.
Utilizzando -O(qualsiasi numero) utilizzando GCC 3.3.1 si possono avere risposte imprevedibili.
Alcune di queste risposte imprevedibili possono essere viste con i seguenti bug inviati a GCC.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12590
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10655
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=8440

VERSIONE: 1.2

LOG MODIFICHE:

Nuove versioni di questo documento possono essere trovate su http://cvs.jg555.com/viewcvs.cgi/lfs-hints