Newsgroup: it.comp.lang.c
Titolo: numeri interi e cast

Ciao a tutti, volevo sapere se fa differenza in prestazioni sommare due
variabili di tipo int e due di tipo float.
E poi si puo' fare il cast da float a int? Che so, se ho dei numeri con
due cifre dopo la virgola e' ragionevole moltiplicarli tutti per 100 e
da li' in poi trattarli tutti come interi?
Grazie
-- 
Davide Cittaro
Drop WINDOWS if you want to reply

 Grazie
ciao

 positivi...)
Purtroppo sono numeri anche grandicelli, maggiori di 256 per
intenderci..
Gia' che ci sono allora vorrei chiedere se esistono delle tabelle o che
altro dove siano riportate in ordine di efficienza le varie operazioni
che si possono fare (oltre alle addizioni, anche la verifica di una
condizione, un cast e via dicendo).
Grazie ancora.


 ciao
Ciau

 Perché questo dovrebbe essere piů veloce ?
perche` deve cambiare lo stato di meno bit...

 condizione, un cast e via dicendo)
Ma sinceramente non lo so, cmq non ci dovrebbero essere problemi si sta
parlando di picosecondi...

 
Su moderni processori a 32 bit le operazioni + veloci sono quelle a 32 
bit, usare short o char fa risparmiare spazio, ma non credo che 
velocizzi le operazioni aritmetiche. Piuttosto, velocizza ampi 
spostamenti di memoria, questo si.
Tra l'altro, a proposito di efficienza, se quello è il problema forse è 
meglio lavorare fin da subito con aritmetica fixed point, senza neanche 
passare per i float...
Daniele

 passare per i float...
cioe`?

 interi?
In alcuni ambiti si`. In ambito finanziario, ad esempio, si opera solo
con numeri interi (in pratica numeri decimali fixed point) per evitare
problemi di approx con i numeri in floating point.
L'altro caso e` quando si deve avere un algoritmo estremamente veloce e
non si e` interessati ad una precisione elevata. In questo, pero`, devi
tenere conto che avrai almeno una moltiplicazione floating point (per
portarti in fixed point) e bisogna valutare se ne vale veramente la
pena.
Luca
-- 
Home: 
http://kronoz.cjb.net
42

 
Cioè su 32 bit, si decide che i primi N + significativi rappresentano la 
parte intera e gli M=32-N meno significativi sono la parte frazionaria.
Per intenderci, un numero fixed point 24.8 (N=24, M=8) si convertirebbe 
in un float dividendo per 2^8 = 256, in questo modo:
unsigned long fixed = ...;
float f = (float)fixed / 256.0;
e viceversa:
unsigned long fixed = (unsigned long) (f * 256.0);
Il fatto di usare una potenza di due (256 in questo caso) rispetto a una 
pot. di 10 migliora le prestazioni, a scapito della precisione.
Le somme/sottrazioni sono identiche a quelle sugli interi, i problemi 
sorgono con la moltiplicazione e divisione. Per la moltiplicazione, in 
particolare, serve usare temporaneamente un intero a 64bit. Peccato che 
in C standard non ci sia un tipo intero garantito con minimo 64bit.
Per maggiori dettagli, cerca "fixed point math" su google...
Daniele

 e i float (4 byte) 30%...
che prove hai fatto ? su che piattaforma ?  e come hai ottenuto
i tempi ?
Giorgio

Giorgio Pastore wrote:

per curiosità ho fatto qualche prova, piattaforma i386 (pentium3), linux ma
non utilizzando il C. questo è il sorgente (per nasm):
segment .text
global _start
_start:
        mov ecx,-1
        mov eax,1
        mov ebx,4
        mov edx,9
.lo
        add eax,ebx
        add edx,ebx
        loop .lo
        mov eax,1
        xor ebx,ebx
        int 80h
cambiando le istruzioni all'interno del loop in add al,bl / add dl,bl o in
add ax,bx / add dx,bx non ho ottenuto differenze apprezzabili (i tempi sono
stati misurati con "time") ed anzi, i risultati migliori li ho ottenuti con
add tra addendi di 32bit (probabilmente un caso).
Quindi se in C si ottengono tempi migliori con gli short forse è colpa del
compilatore oppure non è stata abilitata sufficiente ottimizzazione.
Ciao
-- 
none

 iterazine.
un test piů scrupoloso inserirebbe dei nop in modo da allineare appunto il
codice, in modo da non rompere la pipeline e massimizzare il prefetching..
comunque ho cercato nel loop di evitare le situazioni di stallo.
Per quanto ne so io fino al pentium3 il prefetcher legge sempre i soliti
16bytes e la cacheline č di 32bit
Tra i 3 codici, quello che risente di piů della mancanza
dell'allineamento č quello che prevede l'uso dei registri a 8bit (ho fatto
2 conti proprio adesso con una objdumpata e una calcolatrice.
Salvo errori:
8 bit: prefetch di sole 5 istruzioni
16 bit: prefetch di 15 istruzioni (praticamente questo č quasi allineato)
32 bit: prefetch di 12 istruzioni)
Ho rifatto i test con gli allineamenti e ancora i risultati si equivalgono,
quindi in un ciclo di 4miliardi di ripetizioni pare che alla fine non ci sia
differenza, almeno in assembly. 
 
-- 
none