# -march vs. -mcpu

## Montag[SGU]

A quanto pare esistono dei problemi con march=pentium4 che non esistono con mpcu=pentium4, pero' non ho ben chiara la differenza tra i due.

Qualcuno e' ben disposto a spiegarla in poche parole e in termini semplici che anche un vermetto possa comprendere?

Grazie

----------

## Dani Tsevech

Poche parole semplici? Certo! Due parole: man gcc   :Very Happy:   :Laughing: 

----------

## Montag[SGU]

Hai mai provato a fare 'man gcc'? 'Guerra e pace' e' molto piu' stringato.

No, davvero, all'atto pratico cosa cambia nell'usare uno, l'altro o entrambi?

----------

## Dani Tsevech

Lo so, stavo scherzando  :Very Happy: 

-mcpu = processore

-march = architettura  :Smile: 

----------

## Montag[SGU]

Vado sul pratico cosi' forse riusciamo a far uscire questo thread dall'ineffabile gorgo che lo sta risucchiando.

Ho questi tre casi:

gcc -march=pentium4

gcc -mcpu=pentium4

gcc -march=pentium4 -mcpu=pentium4

Io ero convinto che -march implicasse -mcpu, cioe' che le ottimizzazioni di -mcpu fossero un subset di quelle attivate da -march. Quindi, secondo la mia (distorta?) visione della realta', il primo e il terzo caso dovevano essere equivalenti.

Questa mia logica e' pero' crollata oggi, quando ho dovuto settare i cflags a -march=pentium3 -mcpu=pentium4 per ovviare al problema che attanaglia la compilazione di glibc con gcc-3.2.2.

Per quello chiedevo una minima spiegazione di quali ottimizzazioni comportassero questi due flag (tipo, -msse2 probabilmente viene attivato da -march=pentium4 e non da -mcpu, come invece sarebbe logico aspettarsi, perche' proprio le ss2 sembrano la causa del summenzionato problema di compilazione).

Quindi?

Quindi siate buoni.

----------

## Dani Tsevech

Vuoi un esempio pratico? Architettura del mio Athlon XP: i686

                                     Cpu: athlon xp 2000+

Architettura <> CPU, son due cose indipendenti. Spero di essermi spiegato  :Smile: 

----------

## Montag[SGU]

A questo punto non capisco se sono io che non so spiegarmi o che altro...

@Dani

Le tue precisazioni non mi sono molto d'aiuto visto che non e' cio' che ho chiesto, ma grazie ugualmente.

----------

## teknux

premetto che ne capisco meno di te, ma io dalla risposta di dani ho capito più o meno questo:

architettura = 686 che potrebbero essere celeron, pentium, athlon, duron etc... l'architettura però è comunque 686, diversa dai 586 (es i primi pentium...) e dalle precedenti ARCHITETTURE

cpu = è da intendersi marca e modello, quindi athlon o pntium (modello 4), differenti comunque da un pentium 3 che è comunque una architettura 686, idem per athlon, ora ci sono gli XP, prima erano solo k7 e così via...

spero di aver capito io, e che hai capito anche te ora  :Smile: 

ciauz, tek

----------

## bsolar

Innanzitutto -march include -mcpu.

-mcpu ottimizza, ma non genera istruzioni che rompono la compatibilità tra processori, quindi ad.es. usando -mcpu=pentium4 creo binari ottimizati che però ancora vanno su un i386.

-march invece permette di generare istruzioni specifiche per l'opzione usata, e non è detto che queste istruzioni funzionino su altri processori pur della stessa architettura.

Per quanto riguarda il manuale ciclopico di gcc, puoi usare l'info:

```
# info gcc
```

che è ipertestuale e diviso in categorie (l'Option Index è molto interessante e più comodo da usare) e sia in man che in info puoi cercare con "/".

----------

## Dani Tsevech

bsolar, sei sicuro? Mi pareva fosse il contrario, cpu ottimizza per lo specifico, arch per il generico :/

----------

## bsolar

 *Dani Tsevech wrote:*   

> bsolar, sei sicuro? Mi pareva fosse il contrario, cpu ottimizza per lo specifico, arch per il generico :/

 

 *info gcc wrote:*   

> Intel 386 and AMD x86-64 Options
> 
> --------------------------------
> 
>    These `-m' options are defined for the i386 and x86-64 family of
> ...

 

Inoltre:

 *cat /etc/make.conf wrote:*   

> # -mcpu=<cpu-type> means optimize code for the particular type of CPU without
> 
> # breaking compatibility with other CPUs.
> 
> #
> ...

 

----------

## Montag[SGU]

 *bsolar wrote:*   

> Innanzitutto -march include -mcpu.

 

E' un punto di partenza ed e' quello che sapevo anch'io.

Ma march... "overrides" mcpu? Da quanto ho letto sembra che possano convivere, ma non ne capisco logica e precedenze.

 *Quote:*   

> 
> 
> -mcpu ottimizza, ma non genera istruzioni che rompono la compatibilità tra processori, quindi ad.es. usando -mcpu=pentium4 creo binari ottimizati che però ancora vanno su un i386.
> 
> -march invece permette di generare istruzioni specifiche per l'opzione usata, e non è detto che queste istruzioni funzionino su altri processori pur della stessa architettura.

 

Va bene, ma queste ottimizzazioni sono disponibili anche singolarmente? Mi spiego: march e mcpu possono essere viste come delle "macro" (!) per un certo numero di ottimizzazioni che anche e' possibile attivare singolarmente con appositi flag o sono ottimizzazioni totalmente slegate dagli altri flag? Esempio: in '-march=pentium4 -mcpu=pentium4' sono comprese anche '-mmmx -msse -msse2' o no? Perche' dalla documentazione sembrerebbe di no, ma ho trovato voci contrastanti anche su questo; l'ultimo caso per il problema con glibc: '-march=pentium4 -mno-sse2' ne permette la corretta compilazione anche con gcc-3.2.x (fonte: mailing list gcc).

 *Quote:*   

> 
> 
> Per quanto riguarda il manuale ciclopico di gcc, puoi usare l'info:
> 
> ```
> ...

 

Grazie, pur pescando dalle stesse risorse di 'man', 'info' le rende in effetti quantomeno piu' accessibili. Su gnu.org, inoltre, ho trovato on-line tutta la documentazione, pero' ancora non riesco a carpire le informazioni che cerco.

--

S+E

[ Perche' tanto odio? ]EOL

----------

## Montag[SGU]

 *teknux wrote:*   

> spero di aver capito io, e che hai capito anche te ora 

 

Grazie teknux, il mio problema non e' pero' tanto quello di non riuscire a comprendere il significato semantico di march e mcpu, ma proprio il cosa comporti l'adozione di uno o dell'altro (o di entrambi) ai fini delle ottimizzazioni in fase di compilazione.

--

S+E

[ Perche' tanto odio? ]EOL

----------

## bsolar

OK, ho avuto una discussione in IRC che si può riassumere più o meno così: usa -march  :Rolling Eyes: 

Da quel che mi han detto non ha molto senso usare entrambe le opzioni, ma comunque non mi hanno spiegato cosa otterrei se lo facessi (il che è sospetto. Non è che cazzeggiavano?)

In effetti qualche dubbio ce l'ho. Ad es. se usassi -march=pentium3 -mcpu=i686 cosa ottengo? L'ottimizzazione -march o quella -mcpu? O un misto? O niente del tutto?

Misteri della fede...

----------

## Dani Tsevech

Però march mi ricorda il nome della mia vecchia prof di italiano e latino, cattivissima!   :Twisted Evil: 

----------

## bsolar

Ho indagato un altro po' e mi sembra di aver capito la cosa seguente:

"invento" l'opzione -march-senza-cpu per poter separare la parte -mcpu "inclusa" in -march:

-march = -march-senza-mcpu -mcpu (divido l'ozione in due)

quindi:

-march=A = -march-senza-mcpu=A -mcpu=A

-march=A -mcpu=B = -march-senza-mcpu=A -mcpu=B

-mcpu=B -march=A = -march-senza-mcpu=A -mcpu=A

Ma forse sono solo idiozie...

----------

## Montag[SGU]

Vediamo se ho capito cosa intendi (mi aiuto con delle parentesi):

```
(-march) = (-march-senza-mcpu) + (-mcpu)
```

quindi:

```

(-march = A) = (-march-senza-mcpu=A) + (-mcpu=A)

(-march = A) + (-mcpu = B) = (-march-senza-mcpu = A) + (-mcpu = B)

(-mcpu = B) + (-march = A) = (-march-senza-mcpu = A) + (-mcpu = A)

```

E' giusto?

Perche' questo vorrebbe dire che il risultato della compilazione cambia a seconda dell'ordine con cui vengono passati i parametri. E' davvero cosi' o ti e' sfuggito un errore?

O forse posso pensare che B e A siano processori della stessa famiglia, con B "figlio" di A? (tipo: A ha un subset delle istruzioni di B)

Per come la intendo io: il compilatore genera prima il codice ottimizzato ma compatibile che soddisfa il parametro '-mcpu' e poi procede  aggressivamente, rompendo la compatibilita' ottenuta, secondo quanto detto da '-march'. 

Secondo questa logica, nel caso di '-march=pentium3 -mcpu=pentium4', il codice generato non sarebbe ottimizzato per SSE2, ma solo per SSE, in quanto '-mcpu' punta al mantenimento della compatibilita' verso il basso...

Cosi' si spiegherebbe anche la stringa '-march=pentium4 -m-no-sse2' che ho visto usare sulla mailing list di gcc, e anche '-march=pentium3 -msse2' guadagnerebbe senso.

A questi potrei pero' aggiungere altri casi privi di logica... uno per tutti: '-march=pentium3 -mmmx -msse -msse2' 

Ci sono evidenti sovrapposizioni tra le ottimizzazioni attivabili dai vari flag ('-mmmx' e '-msse' sono inutili in questo caso?) e, per tornare al mio quesito iniziale, sarebbe utile sapere chi fa cosa e in che modo.

L'ultima perplessita' della giornata e' ancora relativa al "guasto" di glibc (sempre li' vado a parare):

- compilarlo con '-march=pentium4' porta all'errore

- compilarlo con '-march=pentium4 -m-no-sse2' no

- compilarlo con '-march=pentium3 -msse2' no

eppure sembrano proprio essere le ottimizzazioni di sse2 in '-march=pentium4' a dar problemi... che dovrebbero corrispondere a '-msse2'! 

A questo punto non sono piu' neppure tanto convinto che cio' che ho appena scritto corrisponda a verita'... non ho provato in prima persona tutte le combinazioni dei parametri e mi sono fidato della parola di chi ne sapeva piu' di me, ma forse e' venuto il momento di allungare il mio codino di verme verso il fuoco per verificare come stanno realmente le cose.

A presto per ragguagli.

----------

## bsolar

 *Montag[SGU] wrote:*   

> Vediamo se ho capito cosa intendi (mi aiuto con delle parentesi):
> 
> ```
> (-march) = (-march-senza-mcpu) + (-mcpu)
> ```
> ...

 

Onestamente, non lo so...

Parto dal presupposto che l'ultima opzione "overridda" la prima, ad es:

```
# df -h -m

Filesystem           1M-blocks      Used Available Use% Mounted on

/dev/root                20905     10837     10068  52% /

# df -m -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/root              21G   11G  9.9G  52% /
```

L'ultima opzione che compare ha il sopravvento.

Quindi:

```
(-march) = (-march-senza-mcpu) + (-march-mcpu)
```

Per differenziare il -mcpu di -march dall'opzione esplicita -mcpu... fa schifo, fa niente  :Wink: 

```
(-march = A) + (-mcpu = B) = (-march-senza-mcpu = A) + (-march-mcpu = A) + (-mcpu = B)

(-mcpu = B) + (-march = A) = (-mcpu = B) + (-march-senza-mcpu = A) + (-march-mcpu = A)
```

Ma come ti ho detto, sto banfando durissimo (anche se a dire il vero al liceo funzionava...  :Wink:   )

----------

