[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[riminilug-general] Re: Curiosità calcolo PI con precisione definita dall'utente



Mi rispondo da solo ... 
Credo di aver trovato il problema!
Probabilmente è un caso di UB (http://en.wikipedia.org/wiki/Undefined_behavior)

Infatti, applicando questa patch al sorgente:

--------------------------------------------- --- pi.c        2015-04-02 08:26:28.174406748 +0000
+++ pi_2.c      2015-04-02 17:54:37.617551065 +0000
@@-15,10 +15,12 @@

 const int LONG_TIME=4000;

+typedef  signed char  CHARTYPE;
+
 // byte[] p;
 // byte[] t;
-char *p;
-char *t;
+CHARTYPE *p;
+CHARTYPE *t;
 int q;

 int main(int argc, char *argv[])
@@-54,10 +56,10 @@

        // p.length = q + 1;
        // t.length = q + 1;
-       p=malloc((q+1)*sizeof(char));
-       t=malloc((q+1)*sizeof(char));
+       p=malloc((q+1)*sizeof(CHARTYPE));
+       t=malloc((q+1)*sizeof(CHARTYPE));

        printf("size of p = %d\n", sizeof(p));
        printf("size of t = %d\n", sizeof(t));
------

.. Il programma funziona bene:

----------------------------------
pi@raspberrypi~/CSources $ ./pi 100
pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170682
0 seconds to compute pi with a precision of 100 digits.
17255 Useconds to compute pi with a precision of 100 digits.
----------------------------------

In pratica ho cambiato la definizione di char con typedef  signed char  CHARTYPE; ed utilizzando CHARTYPE, ho dichiarato forzatamente il char come signed.
Probabilmente il compilatore nel raspberry, prende per default un tipo unsigned e poi fa casino nella conversione ... 
Inizialmente pensavo che il problema fosse nella diversa indianity tra le due architetture .. 

​:)​




Sent with MailTrack

Il giorno 2 aprile 2015 16:14, Gabriele Zappi <gabriele.zappi@xxxxxxxxx> ha scritto:
Ciao, vi sottopongo questa cosa "curiosa" che mi è capitata...

Generalmente, quando voglio fare dei test di performance di calcolo, anziché utilizzare i vari benchmark a disposizione (che darebbe sicuramente risultati più efficienti e attenbili, ma sarebbe troppo facile, e quindi poco divertente :DDD), uso dei miei programmetti in C che fanno diversi tipi di calcoli (numeri primi fino a, Fast Fourier Transform, Gaussiane, ecc. ecc. ) e casualmente sono incappato in questa cosa strana: 

Stavo facendo delle prove di esecuzione e dei confronti tra il mio PC (basato su core Intel al lavoro e AMD a casa) e il mio Blackberry PI 2 .. 
Un sorgente in C che calcola il numero Pigreco con un numero arbitrario di decimali dopo la virgola, che avevo scritto molti anni fa scopiazzando l'algoritmo dalla Rete (che usa integer facendo somme,  sottrazioni, divisioni con gestione del riporto e moduli), è uno dei sorgenti utilizzato per i miei test e confronti .. ma è l'unico che mi ha fatto saltare sulla sedia quando ho guardato i risultati! 
Al di là della differenza nel tempo di esecuzione tra le due architetture (che ci sta!), il fatto strano è che il codice compilato su piattaforma intel/amd (indifferentemente 32 o 64bit), mi restituisce correttamente 3.1415..(e altri decimali), mentre quello in ambiente Arm mi ritorna 3.4850..(e altri decimali)...
Mi ricordo che ebbi lo stesso problema quando feci la stessa prova su una prima revision di Ubuntu Phone sul mio Galaxy Nexus, un paio di anni fa, prova a fare un debug veloce con gdb senza venirne a capo, ma poi gli diedi poca importanza pensando che dipendesse da una immaturità del codice usato per quella build, dato che si trattava di una Developer Preview release ... 
Ora invece comincio a pensare che sia un problema del compilatore, che crea codice eseguibile per cui in una determinata condizione può prendere il brench sbagliato??
Nel codice tra l'altro, non vengono neanche usati tipi dato che possono avere diversi sizeof() a secondo dell'architettura (a parte i char * tra 32/64 bit ovviamente, che comunque non prendono parte attiva nel calcolo).

Il sorgente in questione, è allegato alla presente.
Sotto, il confronto riassuntivo con i risultati dello stesso sorgente compilato ed eseguito nei due ambienti
​:​


gcc amd64 4.9.2 su Intel/AMD64  (su jessie/unstable):

gabo@Gabodesktop:~/c$ lsb_release -a
LSB Version:    core-2.0-amd64:core-2.0-noarch:core-3.0-amd64:core.. .... ..
Description:    Debian GNU/Linux 8.0 (jessie)

​gabo
@Gabodesktop:~/c$ dpkg -l gcc
....
||/ Nome                       Versione           Architettura       Descrizione
+++-==========================-==================-
ii  gcc                        4:4.9.2-2          amd64              GNU C compiler

​gabo
@Gabodesktop:~/c$ ./pi 100
pi = 3.141592653589793238462643383279502884197.......
    ^^^^^^^^^^ Ok!
0 seconds to compute pi with a precision of 100 digits.
2641 Useconds to compute pi with a precision of 100 digits.


gcc armhf 4.6.3 su RaspberryPI2  (su Raspbian/Wheezy 7.8 aggiornato):

pi@raspberrypi ~/CSources $ lsb_release -a
....
Description:    Debian GNU/Linux 7.8 (wheezy)

pi@raspberrypi ~/CSources $ dpkg -l gcc
......
||/ Nome                       Versione           Architettura       Descrizione
+++-==========================-==================-==================-=========================================================
ii  gcc                        4:4.6.3-8          armhf              GNU C compiler

pi@raspberrypi ~/CSources $ ./pi 100
pi = 3.48502699702414701520608900095....
     ^^^^^^^^^ ?????????? 
0 seconds to compute pi with a precision of 100 digits.
17042 Useconds to compute pi with a precision of 100 digits.


​Cosa ne pensate?? Il caso di aprire un "bugzilla" su gcc su armhf o mi sugge qualcosa ??​

​Ciao
Gabriele​




--

Best regards,

Gabriele Zappi
http://www.gabrielezappi.net
GNU/Linux user #380098



Sent with MailTrack



--

Best regards,

Gabriele Zappi
http://www.gabrielezappi.net
GNU/Linux user #380098