Go Down

Topic: Ottimizziamo il codice del core di Arduino (Read 28376 times) previous topic - next topic

Maurotec

Ok, il codice mostrato è solo un esempio ricavato da mio codice eseguibile sul Computer.

La classe IPAddress non è dipendente dall'hardware, quindi con poche modifiche
l'ho resa compatibile con la toolchain per x86_64.
Questo mi da la possibilità di scrivere codice di test ed eseguirlo sul Computer,
in questo modo il risultato del test è immediato.

Il codice originale da IPAddress.h è questo:
Code: [Select]
operator uint32_t() const { return *((uint32_t*)_address); };

Intanto il ";" dopo } si deve togliere, cioè deve diventare:
Code: [Select]
operator uint32_t() const { return *((uint32_t*)_address); }

Con il codice sopra avr-gcc si lamenta, come pure gcc sul mio computer.
La soluzione alternativa alla union è la seguente:

Code: [Select]
operator uint32_t() const { uint32_t *dummy_p = (uint32_t*)_address);
                            return *dummy_p; }


Quote

Mettere il risultato in una variabile locale prima di "dereferenziare" modifica effettivamente la richieste
di restringere l'alias?


Non sono in grado di darti una spiegazione del perché funziona, ma funziona, inoltre
io non sono in grado di analizzare il codice asm prodotto e quindi non so qual'è la  soluzione più efficiente.
Questo è un punto su cui ritornare quando l'obbiettivo sarà l'ottimizzazione

English translation:

Ok, the code shown is just an example based on my code executable on the my computer.

The IPAddress class is not hardware dependent, so with a few changes
I made it compatible with the toolchain for x86_64.
This gives me the ability to write test code and run it on the computer,
in this way the test result is immediate.

The original code from IPAddress.h is this:
Code: [Select]
operator uint32_t() const { return *((uint32_t*)_address); };

Meanwhile, the ";" after} must be removed, ie it must be:
Code: [Select]
operator uint32_t() const { return *((uint32_t*)_address); }

With the above code avr-gcc complains, as well as gcc on my computer.
The alternative solution to the union is the following:

Code: [Select]
operator uint32_t() const { uint32_t *dummy_p = (uint32_t*)_address);
                            return *dummy_p; }


Quote
Does putting the result in a local variable before dereferencing actually change the strict aliasing requirements?


I am not able to give an explanation of why it works, but it works, also
I am not able to analyze the asm code product and so do not know what is the most efficient solution.
This is a point on which to return when the goal is the optimization.

matthijskooijman

I had a closer look at this, and I think that your proposed code still violates the strict aliasing rules in C99, but that the compiler is not smart enough to warn about this (or perhaps only with more warnings enabled). AFAIU strict aliasing rules, the union approach _does_ satisfy strict aliasing requirements, so I'll stick with that solution.

PaoloP

Ho clonato il repository Arduino/master e Arduino/ide-1.5.x-avr-toolchain-gcc-4.8.1
Compilando su Windows con CygWin e creando la distribuzione con
Code: [Select]
ant dist (quella ide-1.5.x-avr-toolchain-gcc-4.8.1)  rimane nell'eseguibile un warning riguardante le directory di tipo MS-DOS.

Ho incluso nel file .bat che carica CigWin la riga
Code: [Select]
set CIGWIN=nodosfilewarning
e se lancio il comando
Code: [Select]
ant run
dentro la directory Arduino/build l'IDE parte e se compilo non da nessun messaggio di errore.
Per contro nella distribuzione (file .zip) se lancio l'eseguibile Arduino.exe e compilo mi appaiono i warning relativi a CygWin nella finestra console dell'IDE.
Perchè?

Qualcuno sa come risolvere?

Go Up