Newsgroup: it.comp.lang.vo-clipper
Titolo: C VS VO per Fabrizio (e per tutti) lungo e OT

Ho provato a far girare il tuo bench, e i risultati sono simili, poi
ne ho realizzato una versione diversa per confrontare VO col C
(Borland 5.02).
La routine di base e' simile, con la differenza che anziche'
verificare la durata dell'esecuzione, in questa versione il programma
"gira" finche' non sono trascorsi 3 secondi, vengono conteggiati i
cicli eseguiti.
La routine e' piuttosto "grezza" ma i 3 secondi garantiscono risultati
abbastanza attendibili, inoltre ho inserito volutamente un ciclo
ripetuto 30000 volte per non far pesare piu' di tanto la
GetTickCountLow() nel conteggio.
I risultati (Athlon 800):
VO ---> 5600
C ---> 25400
La routine C usa un servizio BIOS ( int1A ) per cronometrare, si
tratta di una semplice lettura dei tick di sistema, nota che avrei
dovuto mettere 3 * 18.2 (questo e' l'effettivo nr di tick per secondo)
cosicche' il bench e' sbilanciato a favore di VO. Il compilatore e'
usato in modalita' 16 bit.
Nonostante tutto non mi tornano i conti (mi riferisco alle valutazioni
della CA), chissa' quale compilatore hanno usato ?!?
Mi sembra alquanto strano che VO sia 4,5 volte piu' lento del C,
utilizzando solo operazioni sugli interi, in VO dovrebbero essere
supportati nativamente, i risultati mi fanno pensare che non lo siano
(almeno come intendo io).
Seguono i due listati VO e C.
/* VO */
FUNCTION Sync()
	LOCAL timeout := GetTickCountLow() + 1 AS DWORD
	WHILE (GetTickCountLow() < timeout)
	ENDDO
RETURN timeout
FUNCTION X()
	LOCAL i, k, n, timeout AS DWORD
	n := 0
	timeout := Sync() + 30000
	WHILE GetTickCountLow() < timeout
		FOR i := 1 UPTO 30000
			k := i
			k++
		NEXT
		n++
	ENDDO
RETURN Str(n)
/* C */
#include <stdio.h>
#include <dos.h>
union REGS r;
unsigned long GetTicks(void) {
	r.h.ah = 0;
	int86(0x1A, &r, &r);
	return ((unsigned long)
r.x.cx
 << 16) | r.x.dx;
}
unsigned long Sync(void) {
	unsigned long timeout = GetTicks() + 1;
	while (GetTicks() < timeout)
		;
	return timeout;
}
int main() {
	int i, k;
	unsigned long n = 0L;
	unsigned long timeout;
	timeout = Sync() + 3 * 18;
	do {
		for (i = 0; i < 30000; i++) {
			k = i;
			k++;
		}
		n++;
	} while (GetTicks() < timeout);
	printf("%ld\n", n);
	return 0;
}
ciao, acc.   
a...@libero.it

 (almeno come intendo io).
Suggerimenti di CA...
    evitare lo statement X++ in quanto e' piu' lento dell'analogo X := X+1
    VO gira in un ambiente multitasking, affetto quindi dalla contemporanea
esecuzione di altri processi.
    Il codice a 32 bit in modo protetto e' notoriamente più lento, nelle
operazioni in questione, di quello a 16 bit in modalità reale.
    Il codice a 16 bit non hai specificato se era eseguito in finestra o
direttamente dalla modalità reale del DOS.
    Il confronto andrebbe fatto con codice a 32 bit di una applicazione
GUI-Win32.
Le verifiche di CA presumo siano eseguite sulla gestione DBase e non sui
costrutti del linguaggio.
In tal caso le DLL inserite nel VO equivalgono in prestazioni quelle scritte
direttamente in C in quanto sono scritte, nelle primitive di accesso, in C.
La classificazione di VO come linguaggio e' da intendendersi ad un livello
di astrazione molto piu' elevato del C.
Poco importa se una esecuzione applicata ad un milione di records mi perde 5
secondi nel loop su un totale di 1 ora, facendomi risparmiare 1 giorno nello
sviluppo del codice.
Inoltre, valutando il codice prodotto dal C e' ovvio che anch'esso le prende
di brutto dal codice ASM, ma non consiglio ASM per i DBase solo perchè
esegue i loop al 100% delle possibilità della macchina.

"acc" <a...@libero.ita> ha scritto nel messaggio
news:38v27u0aqfi718s7h...@4ax.com...

Secondo me, comunque non sono confrontabili in quanto non sai quanto tempo
impiga il VO ad eseguire la funzione GetTickCountLow() e il C ad eseguire
GetTicks().
Se rivedi la mia routine l'avevo utilizzata in modalitą neutra rispetto al
ciclo FOR
Ciao,
    Fabrizio Malaguti


Questa non la sapevo. Interessante.
Ciao,
    Fabrizio Malaguti

 esegue i loop al 100% delle possibilità della macchina.
Già, mi cadono i pochi capelli rimasti solo a pensare di scrivere un
gestionale in ASM... :-)
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg

 Non dovrebbe. In C, a quanto ne so, è, in generale, più veloce.
In C e' certamente piu' veloce in quanto le variabili vengono posizionate,
quando possibile, nei registri della CPU. L'incremento o decremento unario
e' quindi piu' veloce.
In VO invece non esiste questa ottimizzazione e l'incremento avviene in RAM,
consumando piu' cicli di CPU.

ciclo FOR
La tua routine cosi' com'e' sul mio PC non e' affidabile, perche'
viene eseguita in un tempo troppo breve. Ok, basterebbe aumentare il
numero di cicli di test, ma io in genere preferisco utilizzare il mio
sistema (forzare la durata). Di solito uso una chiamata del BIOS che
alza un flag allo scadere del tempo, purtroppo mi e' impossibile
utilizzarla per la mia scarsa conoscenza di VO (e poi non ho l'SDK).
BTW provero' a vedere se riesco a rifare il tutto sotto windows
utilizzando un timer, che come sistema e' simile a cio' che intendevo.
ciao, acc.   
a...@libero.it

esegue i loop al 100% delle possibilità della macchina.
Non credo che nel particolare esempio (incremento di interi) ci sia
molta differenza tra C e ASM.  Nella maggior parte dei compilatori C
"seri" una istruzione del tipo i++, viene tradotta nel corrispondente
inc <reg> (supponendo un'ottimizzazione nei registri).
ciao, acc.   
a...@libero.it

consumando piu' cicli di CPU.
Sei sicuro di questo ?
ciao, acc.   
a...@libero.it

 inc <reg> (supponendo un'ottimizzazione nei registri).
Aggiungerei che nel C, opzionalmente, viene prodotto il corrispondente
output ASM, ne VO questo non e' possibile (e non avrebbe senso). Quindi
l'ottimizzazione nei registri non puo' essere applicata.

 Sei sicuro di questo ?
File di Help CAVO20.HLP
Sottomenu "How To..."
Sottomenu Performance Tuning
"They May Look Cool, But...
Please do not use the postfix ++ and -- operators (prefix ones are OK).  For
simple (e.g. numeric) types there is no improvement in code quality.  For
complex types (instance variables, dynamic array elements, etc.) the code
quality is actually worse (than using a:=a+1 or a += 1 )!"
Il suggerimento dice che non ci sono miglioramenti nella forma X++, quindi
non vengono usate le variabili nei registri.
Le cose invece peggiorano per i tipi complessi (non in questo caso).

 In VO quella e' un ottimizzazione sintattica
Hai coniato un nuovo termine per l'occasione? :-)


 Questo e' assolutamente falso.
Dici? Eppure anch'io ho constatato tante volte la stessa cosa...


 quality is actually worse (than using a:=a+1 or a += 1 )!"
E' normale che gli operatori postfissi siano meno efficienti di quelli
prefissi in quanto i primi abbisognano di una variabile temporanea dato
che devono restituire un valore diverso da quello che assume la
variabile operando. Non è invece comprensibile il perché a++ debba
essere meno efficiente di a += 1 o a = a + 1...


 Hai coniato un nuovo termine per l'occasione? :-)
estetica?  Che al fine del codice non giova?
 ;-)
Le prime volte che scrivevo in C, preso dalla potenza del linguaggio,
scrivevo statements talmente complessi da risultare illeggibili!

 essere meno efficiente di a += 1 o a = a + 1...
Non so che dire, fatto sta che ho fatto un copia-incolla direttamente
dall'HelpFile della 2.0.

"pimpa" <xxx@xx.x> ha scritto nel messaggio
news:D3Nc8.5946$E33.1...@twister1.libero.it...

comunque ho scoperto che il tutto è vero tranne quando le variabili sono
tipizzate (in VO 2.5)
Ciao,
    Fabrizio Malaguti

 ciao, acc.   
a...@libero.it

 scrivevo statements talmente complessi da risultare illeggibili!
Infatti è una delle classiche tentazioni in cui si incorre quando si
utilizza il C. Per fortuna che i compilatori sono in genere abbastanza
furbi da non richiedere tali statements per ottimizzare il codice.


 progettare un CAD allora utilizza direttamente C / ASM.
Capito. Comunque tieni presente che io il C affiancato al Clipper l'ho
utilizzato solamente per fare cose che in Clipper non si potevano
proprio fare e mai per motivi di efficienza. Come ho detto più volte,
nei gestionali l'efficienza è legata agli accessi al disco e su quelli
non ci si può fare niente neanche in ASM.



Nel nostro caso abbiamo affiancato il C al Clipper anche per efficienza.
Ciao,
    Fabrizio Malaguti


l'ottimizzazione nei registri non puo' essere applicata.
Secondo me e' il contrario, c'e' forse qualche valida ragione perche'
VO non dovrebbe produrre un output in ASM ?
Se a te non serve, non e' detto che sia cosi' anche per altri.
Quanto all'ottimizzazione nei registri, non vedo alcuna
controindicazione alla sua implementazione, oltre a non capire quale
nesso abbia con la generazione di un output ASM.
ciao, acc.   
a...@libero.it

Dici? Eppure anch'io ho constatato tante volte la stessa cosa...
No, perlomeno non lo stesso codice. Posso essere d'accordo con te che
diversi programmi portati in ambiente a 32 bit non hanno mostrato
benefici in termini di velocita', ma il motivo e' da ricercarsi nel
fatto che probabilmente nulla e' stato fatto in proposito.
Nella maggior parte dei casi si tratta di una scelta obbligata, solo
per girare nel "nuovo ambiente", o per sfruttarne alcune
caratteristiche.
Se pero' prendi un programma con codice a 16 bit e lo riscrivi a 32
bit, il salto di prestazioni c'e' eccome.
Un caso particolare di calo di prestazioni invece si riscontra se il
programma e' costretto a passare continuamente da 'protected mode' a
'real mode', generalmente per utilizzare funzioni DOS/BIOS non
rientranti, ma in questo caso non bisogna lasciarsi trarre in inganno,
il problema non riguarda l'utilizzo di codice a 32 bit, che per inciso
non necessariamente implica un utilizzo in protected mode, bensi' una
deficienza di certe architetture che ben conosciamo ;-P
ciao, acc.   
a...@libero.it

progettare un CAD allora utilizza direttamente C / ASM.
Beh, anche su questo.
ciao, acc.   
a...@libero.it

non ci si può fare niente neanche in ASM.
Enno, caro Enrico, tra C/ASM e Clipper e' stato amore a prima vista,
come testimoniato da centinaia di realizzazioni.
Non puoi mica liquidare tutto cosi' !  Ormai per me programmare in
Clipper senza avere un compilatore C e un Assemblatore a portata di
mano e' una prospettiva inaccettabile. Mi sentirei un pesce fuor
d'acqua.
ciao, acc.   
a...@libero.it

 d'acqua.
E' un tuo problema. :-)


 bit, il salto di prestazioni c'e' eccome.
Mi puoi spiegare come mai il seguente programmino
#include <stdio.h>
#include <time.h>
int main()
{
    long i;
    clock_t tick = clock();
    for ( i = 0; i < 300000000L; ++i );
    printf( "%d", clock() - tick );
    return 0;
}
se compilato con il Borland TurboC++ 1.01 (16 bit) risulta almeno 20
volte più veloce rispetto alla sua compilazione con il Borland C++ 5.5.1
(32 bit)?


 oltre a non capire quale nesso abbia con la generazione di un output ASM.
Se il codice viene tradotto integralmente in ASM, e non mediante costrutti
preconfezionati, e' ovvio che la scelta delle istruzioni ASM e la loro
disposizione lasciano libero spazio all'ottimizzazione (in funzione della
CPU oltretutto).
Se invece lavora come penso io, ovvero tramite delle MACRO parametrizzate
dove vengono incapsulate le call e le istruzioni del linguaggio VO puoi
facilmente capire che il compilatore funziona solo come "collante",
introducendo oltretutto una notevole complessità per l'uso delle variabili
non tipizzate e per le caratteristiche di compatibilità "old style" del
clipper.
A titolo di esempio, le "PROCNAME/PROCLINE" che aumentano del 30% la
dimensione del codice.

 (32 bit)?
probabile che clock() esegua una call BIOS... commutazione tra REAL e PROT
quindi

 quindi
In realtà pensavo che tale tempo potesse essere completamente
trascurabile dato che vengono eseguite solo due chiamate alla clock(),
all'inizio e alla fine del programma. Invece ho tolto completamente la
misurazione del tempo e, cronometrando dall'esterno, il risultato è
stato che la versione a 32 bit era circa 3 volte più veloce di quella a
16. Quindi, almeno in questo semplice caso, sembra che abbia ragione
acc...


...beh, a dire il vero in 10 anni di clipper ho usato l'Assembler solo per
formattare i dischi ed il C solo per alcune routine di gestione video,
alcune delle quali poi riscritte in clipper (ombre delle finestre
trasparenti, ed altre fesserie del genere) o per riscrivere alcune funzioni
trigonometriche che non mi davano sufficiente precisione.
Non mi ricordo comunque di aver visto pesanti inserti di C o di Assembler
nelle 1000 e 1000 procedure clipper che mi sono passate tra le mani.
Ovviamente clipper sempre in ambito gestionale.
by
Massimo
"acc" <a...@libero.ita> ha scritto nel messaggio
news:g9887u4oqi95bfhue...@4ax.com...


 stato che la versione a 32 bit era circa 3 volte pių veloce di quella a


 risultava ancora una certa paritą, ma vado a memoria di qualche anno fa.
Ma il primo processore Intel a 32 bit non era il 386?


clipper.
Alla fine comunque _DEVE_ generare codice LM.
ciao, acc.   
a...@libero.it

acc...
In effetti questa e' sempre stata una spina nel fianco di Windows, fin
dalla sua nascita. Anche se va' detto che in molti casi e' possibile
rimediare utilizzando alcune funzioni 'alternative', a tal proposito
ricordo che la quasi totalita' delle funzioni DOS sono ormai esenti da
questo problema, purtroppo cosi' non e' per quelle del BIOS.
ciao, acc.   
a...@libero.it

Ovviamente clipper sempre in ambito gestionale.
Parecchie librerie per Clipper (in genere le migliori) sono in ASM/C.
Ovvio che per scrivere routine gestionali il Clipper da solo basta e
avanza.
ciao, acc.   
a...@libero.it

 Alla fine comunque _DEVE_ generare codice LM.
OK...
Prova a dare un occhiata al codice ASM prodotto dal compilatore C e poi
confrontalo con qualche esempio di MACRO ASM della stessa MS.
Dimmi se tale codice e' essenziale come quello che un programmatore
scriverebbe con il MACRO ASM o se contiene delle istruzioni e tecniche
macchinose per fare le stesse cose.
Io sono del parere che per tanto ottimizzato possa essere, e' SEMPRE piu'
complesso del codice ASM scritto di pugno.
Aggiungi poi un'ulteriore complessità, a fronte di regole sintattiche piu'
permissive, per quello VO.
E' questo che ti volevo dire, hanno target diversi anche se sono in ASM.

 avanza.
Infatti è questo che volevo affermare.
