Newsgroup: it.comp.programmare
Titolo: [Vecchio Confronto Azatoth]

Stavo facendo pulizia di file sparsi nel mio HD, quando visionando la
directory dove salvo i post che trovo interessanti ne ho trovato uno di
Azatoth.
Visto che sul NG nessuno uso Fortran, e a quanto pare io sono l'unico
(ma poco esperto) a usare questo linguaggio e visto che Azatoth era
interessato a espandere i suoi confronti ad altri linguaggi(*), ho
deciso di riesumare questo vecchio post, che ho trovato interessante
e grazie al quale mi sono avvicinato al VB per poi fuggirne :).
Non riporto l'intero post per non appesantire il messaggio, pero' do' le indicazioni per
chi volesse rivederlo:
=====================
Soggetto:[CONFRONTO] Python vs C vs Visual Basic, pessimizzazione
introdotta
it.comp.programmare
   Data:2002-10-10 07:18:42 PST
=====================
Il codice C proposto  da Azatoth e':
=====================
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <memory.h>
#define MAX_CYCLES 1000000
void experiment( void ) {
 int sum = 0;
 int i = 0;
 for( i = 0; i < MAX_CYCLES; ++i )
  sum = ( sum + i ) % 999999;
}
int main( ) {
 clock_t c = clock();
 clock_t d;
  experiment( );
 d = clock() - c;
 printf( "It tooks %f to performs", ( float ) d / ( float )
CLOCKS_PER_SEC );
 return 0;
};
=========================
i risultati a cui Azatoth e' pervenuto su un PIII a 1 GHz sono:
MISURE
    MAX_CYCLES = 10K
        Tp(10K) = 0.0089 s
        Tv(10K) = 0.0012 s
        Tc(10K) = 0.0000 s
    MAX_CYCLES = 100K
        Tp(100K) = 0.1038 s
        Tv(100K) = 0.0194 s
        Tc(100K) = 0.0050 s
    MAX_CYCLES = 1000K
        Tp(1000K) = 1.0663 s
        Tv(1000K) = 0.1418 s
        Tc(1000K) = 0.0490 s
Il codice che propongo io su un K6-III e':
=========================================
program prova
implicit none
integer,parameter :: max_cycles = AD_LIBIDUM
integer           :: somma=0,i = 0
real              :: t1
do i=1,max_cycles
       somma = mod((somma+i),999999)
enddo
call cpu_time(t1)
write(*,*) 'tempo -> ',t1     ! l'ho inserito solo perche' il codice di
                              ! riferimento esegue operazioni analoghe
end program prova
=========================================
vediamo quidi i risultati:
MAX_CYCLES = 10K
        Tp(10K) = 0.0089 s
        Tv(10K) = 0.0012 s
        Tc(10K) = 0.0000 s
->      TF95(10K) = 0.000000E+00 s
    MAX_CYCLES = 100K
        Tp(100K) = 0.1038 s
        Tv(100K) = 0.0194 s
        Tc(100K) = 0.0050 s
->      TF95(100K) = 0.000000E+00 s
    MAX_CYCLES = 1000K
        Tp(1000K) = 1.0663 s
        Tv(1000K) = 0.1418 s
        Tc(1000K) = 0.0490 s
->      TF95(1000K) = 3.000000E-02 s
Mhhh niente male, niente male, ovviamente ho compilato senza
ottimizzazioni. ma con MAX_CYCLES = 1E9 quanto ci mette?
Fortan95 senza ottimizzazioni
=============================
:/tmp$ ifc prova.f90
   program PROVA
17 Lines Compiled
:/tmp$ ./a.out
 tempo ->    26.47000
==============================
C (gcc 3.2.1) senza ottimizzazioni
==================================
:/tmp$ cc prova.c
:/tmp$ ./a.out
It tooks 117.370000 to performs
==================================
Mhh a questo punto mi si potrebbe dire che il codice F95 non e' proprio
identico al codice C... e vabbe'
=============================
#include <stdio.h>
#include <memory.h>
#define MAX_CYCLES 1E9
int main() {
  int sum = 0;
  int i = 0;
  for( i = 0; i < MAX_CYCLES; ++i )
    sum = ( sum + i ) % 999999;
  return 0;
}
==============================
:/tmp$ cc prova.c
:/tmp$ time ./a.out
real    1m54.886s
user    1m54.870s
sys     0m0.010s
mi pare si siano guadagnati circa 3 secondi, ma siamo molto lontani dai
26 secondi del F95.
Credo che possa bastare :).
--
(*) Tutti sanno quali siano le posizioni di Azatoth in
campo informatico e quanto possa essere attendibile un test del genere,
pero' se si effettuano dei semplici confronti tra soluzioni possibili
usando linguaggi diversi, cercando di non dire X e' meglio di Y, o di
voler convertire tutti a seguire la giusta via, ma lasciando che siano i
lettori vedendo il codice di diverse implementazioni per uno stesso
problema a trarne delle conclusioni, forse si puo' portare avanti una
discussione seria e proficua per tutti.

 di Azatoth.
<trollMode>
Si tratta sicuramente di un errore.
Cancellalo.
</trollMode>
:-9
-- 
Gerolamo

Il Tue, 26 Aug 2003 13:09:30 GMT, Gerolamo fece sapere che:

LOL invece sono contento di averlo conservato, non mi pare di ricevere
piu' test sulla velocita' e sulla strabiliante supremazia del C++ (*)
rispetto al altri linguaggi meno nobili(**) dopo le mazzate prese :) 
(*) I test in realta' si riferiscono ai compilatori ed agli interpretri
(come molti piu' volte hanno fatto notare e non al linguaggio, e poi
paragonare un programma compilato con uno interpretrato non mi pare sia
"sportivo" :)
(**) Il C++ sara' pure potente, flessibile, complesso, complicato, ed
usato solo dai veri programmatori(***) in quanto l'olimpo informatico deve
essere inaccessibile a chi usa l'informatica come una semplice appendice
al proprio lavoro, ma non sempre e' la scelta migliore 
per un determinato problema, come molti su questo NG hanno piu' 
volte *abbondantemente* dimostrato.
(***)Che poi cosa e chi sia un programmatore e' da definire.
<IronicMode>
Ma non capisco come mai il caro *AzaTotti* non abbia nulla da ridire sulle
incredibili performance offerte dal FORTRAN (quello che lui chiama
"salma"), che supera di gran lunga, e su macchine piu' vecchie, seguendo
i suoi stessi bench, i risultati che con tanto ardore sventola al modo
intero per affermare l'onnipotenza del C++.
Sara' mica corso in libreria a comprare "Fortran95 for Dummies"?
</IronicMode>
Happy free coding a tutti.

 
 > [CUT]

 > [CUT]
Due punti.
1. Quanti bytes occupa un integer default in fortran95?
2. Secondo me bisognerebbe fare i test con le ottimizzazioni abilitate 
in entrambi.
Ciao.
  -Ema-

 in entrambi.
Vorrei un chiarimento, per quanto ne so l'uso di ottimizzazioni puo'
pregiudicare le performance del binario se questo gira su processori (os
e architettura identiche ovviamente ;)) diversi da quello su cui e'
avvenuta la compilazione, quindi credo si dovrebber fare riferimento a
codice non ottimizzato, in quanto e' si rilevano meglio le capacita' del
compilatore. Ovviamente e' solo una mia considerazione personale.
Nel caso dell'uso delle ottimizzazioni si dovrebbe usare lo stesso processore, 
e testare non le varie combinazionini di ottimizzazione, ma solo quelle comuni 
ai compilatori, quali ad esempio MMX SSE ecc. nonche' l'ottimizzazione dei loop, 
se poi c'e' qualcuno che ha un computer a piu' processori si potrebbero testare
anche le ottimizzazioni per il calcolo parallelo.
[*] Letto sulla documentazione, per maggiore sicurezza ho fatto una
provina ed ecco un test con codice C e F95
========F95========
program prova
implicit none
integer :: i=0
do while(i>=0)
  i=i+1
enddo
print *, i-1
end program prova
==================
:/tmp$ ifc prova.f90
:/tmp$ time -p ./a.out
 
2147483647
real 10.73
user 10.73
sys 0.01
==========C========
#include<stdio.h>
int main(){
	int i=0;
	while(i>=0){
		i++;
	}
	printf("%d\n",i-1);
}
=======================
:/tmp$ gcc-3.3 prova.c
:/tmp$ time -p ./a.out
2147483647
real 24.39
user 24.14
sys 0.00
hehe ;), ma ricordiamoci che non si tratta di benchmark affidabili anzi,
ed i tempi in questo caso non significano nulla :)
--
Happy coding

 ottimizzazioni per il calcolo parallelo. 
Potresti porstare i parametri che passi al compilatore?
Inoltre suggerirei di misurare il tempo solo dell'esecuzione del ciclo.
Ciao.
 -Ema- 


Sia con gcc che con ifc non ho dato nessun parametro.
il comando time serve proprio a darmi la durata dell'esecuzione.
Scusa se ho frainteso ma puoi essere piu' chiaro : 

 Scusa se ho frainteso ma puoi essere piu' chiaro : 
Ne codice c che stai usando che riporto per comodita':
#include <stdio.h>
#include <memory.h>
#define MAX_CYCLES 1E9
int main() {
   int sum = 0;
   int i = 0;
   for( i = 0; i < MAX_CYCLES; ++i )
     sum = ( sum + i ) % 999999;
   return 0;
}
Non vedo istruzioni per misurare il tempo impiegato. Ne deduco che hai 
misurato il tempo da fuori. Ritengo che, come nell'originale, 
bisognerebbe usare l'istruzione clock prima e dopo il ciclo.
Bisognerebbe inoltre sostituire 1E9 con 1000000000, diversamente il 
numero viene trattato come un float, penso, e questo ovviamente non va 
affatto bene.
Il fatto e' che con i processori di adesso un ciclo cosě semplice 
dovrebbe essere fatto solo con i registri della CPU. Non mi spiego 
pertanto la differenza.
Non sono un fun sfegatato del C/C++ anche se lo uso spesso e mi piace 
molto; sono piuttosto un opportunista e cerco di usare il linguaggio che 
mi permette di ottenere il risultato migliore con il minimo dello sforzo 
di volta in volta. So a grandi linee come il C viene tradotto il 
linguaggio macchina e non mi spiego un tale differenza. Tutto qua'.
Ciao.
  -Ema-

Prova con queste piccole modifiche:
#include <stdio.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <memory.h>
#define MAX_CYCLES 1000000000
int main() {
         clock_t c = clock();
         clock_t d;
         register int sum = 0;
         register int i = 0;
         for( i = 0; i < MAX_CYCLES; i++ )
                 sum = ( sum + i ) % 999999;
         d = clock() - c;
         printf( "It tooks %f to performs",
                 ( float ) d / ( float) CLOCKS_PER_SEC );
         return 0;
}
Io ho ottenuto tempi 10 volte inferiori a quelli del programma originale.
Ciao.
  -Ema-


Nemmeno io sono un sosteniture accanito di un unico linguaggio, ma
preferisco usare lo strumento piu' adatto a un determinato scopo, i post
che faccio non vogliono dimostrare la superiorita' di X o Y ma solo
(dato che non sono un programmatore esperto) comprendere meglio i limiti
ed il funzionamento di X e Y.
Tempo fa ho postato il link ai sorgenti di un programma per calcoli
astronomici (non nel senso delle quantita', ma nel senso di orbite ecc :)
) i sorgenti erano forniti in C++ e Fortran95 se ti interessa vederli
prova a cercare *almabench-1.0.0.tar.gz* 
Tornando al post, tu proponevi il codice:
======================
#include <stdio.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <memory.h>
#define MAX_CYCLES 1000000000
int main() {
         clock_t c = clock();
         clock_t d;
         register int sum = 0;
         register int i = 0;
         for( i = 0; i < MAX_CYCLES; i++ )
                 sum = ( sum + i ) % 999999;
         d = clock() - c;
         printf( "It tooks %f to performs",
                 ( float ) d / ( float) CLOCKS_PER_SEC );
         return 0;
}
========================
vorrei farti due domande pero',
a) memory.h cosa fa in questo caso? server per le dichiarazioni clock_t
   e register?
b) Spesso ho sentito che la dichiarazione register e' assolutamente
   inutile in quanto il compilatore ottimizza molto meglio in
   *automatico* in questo caso invece il fatto che ci siano 2 variabili
   permette di avere risultati migliori?
Bene passiamo alla compilazione sulla mia macchina
:/tmp$ gcc-2.95 programmare.c
:/tmp$ ./a.out
It tooks 55.500000 to performs
Un risultato veramente orribile, cmq per fortuna c'e' gcc-3.3 ;)
:/tmp$ gcc-3.3 programmare.c
:/tmp$ ./a.out
It tooks 10.090000 to performs
Il risultato e' migliore sia rispetto a quello offerto dal gcc-2.95
(come mai tanta differenza pero? il gcc-2.95 fa schifo?), ma e' anche
migliore dei risultati a cui io ero pervenuto in precedenza usando
codice Fortran95 e compilatore ifc.
Inutile dire che mi sono messo a rodere :)
Cosi ho cercato di sistemare un pochino il codice, calcolando solo il
tempo del ciclo e unsado una funzione diversa da mod, che lavori solo
sugli interi, purtroppo la funzione, che esiste e si chiama imod e'
ottimizzata solo per lavorare su numeri interi esprimibili da 16 bit.
Il codice e' quindi:
==================
program prova
implicit none
integer,parameter :: max_cycles = 1000000000
integer           :: somma=0,i = 0
real              :: t0,t1
call cpu_time(t0)
do i=1,max_cycles
       somma = mod((somma+i),999999)
enddo
call cpu_time(t1)
write(*,*) 'tempo -> ',t1-t0    
end program prova
===================
ed i risultati sono identici a quelli che ho postato prima, mi pare
24.47 sec o cmq 24 e qualche cosa, sta di fatto che sono sempre
superiori ai 10 sec. ottenuti con gcc-3.3.
A questo punto non essendo espertissimo nella programmazione non sono
riuscito a migliorare ulteriomente il codice, e ovviamente continuavo a
rodermi, poi ho ricordato che il fortran77 viene visto come un subset
di fortran95, cioe' i compilatori f95 compilano differentemente i codici
che hanno istruzioni in f95 e in f77,  in  quando se si compilano codici con 
estensione in f77 puro si fa riverimento a un 
linguaggio estremamente semplice quale e' appunto il fortran77 e per il
quale i compilatori esistenti hanno raggiunto un affinamento incredibile
(non e' un caso che il f77 sia ancora massicciamente usato) quindi ho
riscritto il codice in fortran77 (che torno ha ribadire il fatto che sia
perfettamente compatibile con f95, in quanto e' un suo subset) e ho compilato, 
il risultato ha dell'incredibile, ecco il codice:
N.B.: Le differenze sono pochissime
================================ 
        program prova
        implicit none
        integer max_cycles 
        integer somma,i
        real    t0,t1
 
        parameter (max_cycles=1000000000)
 
        somma = 0
        i = 0
 
        call cpu_time(t0)
 
        do i=1,max_cycles
                somma = mod((somma+i),999999)
        enddo
        call cpu_time(t1)
        write(*,*) 'tempo -> ',t1-t0    
 
        stop
        end 
===================================
compilato con gcc non e' esaltante come risultati (g77 non e'
nemmeno completamente sviluppato ed aderente allo standard f77, e per
quanto ne so' non ha una grande platea di sviluppatori come g++ e gcc,
che sono tra i migliori e piu' performanti compilatori C/C++ attualmente
disponibili, per cui si deve fare ricorso a prodotti commerciali :(, 
ma questo e' il prezzo che i software di nicchia pagano al Free Software )
:/tmp$ g77-2.95 programmare.f
:/tmp$ ./a.out
 tempo ->   70.6399994
:/tmp$ g77-3.3 programmare.f
:/tmp$ ./a.out
 tempo ->   93.6999969
Risultati davvero *penosi*, ma per fortuna la Intel fornisce il suo
compilatore gratuitamente per usi personali ed ecco:
:/tmp$ ifc programmare2.f90
   program PROVA
27 Lines Compiled
:/tmp$ ./a.out
 tempo ->    1.010000
             ^^^^^^^^
             ^^^^^^^^
Che e' un risultato strepitoso :), direi incredibile, e che conferma che
per avere buone prestazioni occorre un buon programmatore e
possibilmente un buon compilatore :)
Se ho capito bene conosci qualcosa di Assembler, ti mando il codice
assembler prodotto dal compilatore cosi' vedi meglio cosa fa, io non ci
capisco niente, mi piacerebbe sapere qualcosa di piu'.
============= CODICE ASM DEL PROGRAMMA IN FORTRAN =====================
# -- Machine type IA32
# mark_description "Intel(R) Fortran Compiler for 32-bit applications, Version 7.1   Build 20030307Z";
# mark_description "-Xlinker -rpath -Xlinker /opt/intel/compiler70/ia32/lib -I/opt/intel/compiler70/ia32/include -S";
	.ident "Intel(R) Fortran Compiler for 32-bit applications, Version 7.1   Build 20030307Z"
	.ident "-Xlinker -rpath -Xlinker /opt/intel/compiler70/ia32/lib -I/opt/intel/compiler70/ia32/include -S"
	.file "programmare2.f90"
	.text
	.data
	.align 4
	.bss
	.align 4
	.data
	.text
# -- Begin  main
# mark_begin;
       .align    4,0x90
	.globl main
main:
# parameter 1: 8 + %ebp
# parameter 2: 12 + %ebp
..B1.1:                         # Preds ..B1.0
        pushl     %ebp                                          #1.0
        movl      %esp, %ebp                                    #1.0
        subl      $3, %esp                                      #1.0
        andl      $-8, %esp                                     #1.0
        addl      $4, %esp                                      #1.0
        subl      $8, %esp                                      #1.0
        pushl     12(%ebp)                                      #1.0
        lea       8(%ebp), %eax                                 #1.0
        pushl     %eax                                          #1.0
        call      f90_init                                      #1.0
                                # LOE ebx esi edi
..B1.2:                         # Preds ..B1.1
        lea       8(%esp), %eax                                 #14.0
        pushl     %eax                                          #14.0
        call      f90_cputime4                                  #14.0
                                # LOE ebx esi edi
..B1.14:                        # Preds ..B1.2
        addl      $12, %esp                                     #14.0
                                # LOE ebx esi edi
..B1.3:                         # Preds ..B1.14
        movl      $1, %eax                                      #16.0
        .align    4,0x90
                                # LOE eax ebx esi edi
..B1.4:                         # Preds ..B1.4 ..B1.3
        addl      $5, %eax                                      #18.0
        cmpl      $1000000000, %eax                             #18.0
        jle       ..B1.4        # Prob 100%                     #18.0
                                # LOE eax ebx esi edi
..B1.5:                         # Preds ..B1.4
        lea       4(%esp), %eax                                 #20.0
        pushl     %eax                                          #20.0
        call      f90_cputime4                                  #20.0
                                # LOE ebx esi edi
..B1.6:                         # Preds ..B1.5
        push      $mainIOTABLES.33+20                           #22.0
        push      $0                                            #22.0
        call      f_iod                                         #22.0
                                # LOE ebx esi edi
..B1.7:                         # Preds ..B1.6
        movl      $mainSST.32, mainIOTABLES.33+36               #22.0
        push      $mainIOTABLES.33+32                           #22.0
        push      $11                                           #22.0
        call      f_iod                                         #22.0
                                # LOE ebx esi edi
..B1.8:                         # Preds ..B1.7
        flds      24(%esp)                                      #22.0
        fsubs     20(%esp)                                      #22.0
        fstps     EPC_GLA34                                     #22.0
        movl      $EPC_GLA34, mainIOTABLES.33+48                #22.0
        push      $mainIOTABLES.33+44                           #22.0
        push      $11                                           #22.0
        call      f_iod                                         #22.0
                                # LOE ebx esi edi
..B1.9:                         # Preds ..B1.8
        push      $0                                            #22.0
        push      $-1                                           #22.0
        call      f_iod                                         #22.0
                                # LOE ebx esi edi
..B1.10:                        # Preds ..B1.9
        push      $0                                            #24.0
        push      $-1                                           #24.0
        call      f_stop                                        #24.0
                                # LOE ebx esi edi
..B1.11:                        # Preds ..B1.10
        addl      $52, %esp                                     #25.0
        movl      %ebp, %esp                                    #25.0
        popl      %ebp                                          #25.0
        xorl      %eax, %eax                                    #25.0
        ret                                                     #25.0
        .align    4,0x90
                                # LOE
# mark_end;
	.type	main,@function
	.size	main,.-main
	.bss
	.align 4
EPC_GLA34:
	.type	EPC_GLA34,@object
	.size	EPC_GLA34,4
	.space 4	# pad
	.data
	.align 4
mainSST.32:
	.byte 116	# s8
	.byte 101	# s8
	.byte 109	# s8
	.byte 112	# s8
	.byte 111	# s8
	.byte 32	# s8
	.byte 45	# s8
	.byte 62	# s8
	.byte 32	# s8
	.space 3	# pad
mainIOTABLES.33:
	.byte 12	# s8
	.byte 109	# s8
	.byte 97	# s8
	.byte 105	# s8
	.byte 110	# s8
	.byte 32	# s8
	.byte 112	# s8
	.byte 114	# s8
	.byte 111	# s8
	.byte 103	# s8
	.byte 114	# s8
	.byte 97	# s8
	.byte 109	# s8
	.space 3	# pad
	.long 1441812	# s32
	.long 6	# s32
	.byte 3	# s8
	.byte 0	# s8
	.byte 98	# s8
	.byte 0	# s8
	.space 4	# pad
	.long 5	# s32
	.space 4	# pad
	.byte 9	# s8
	.byte 0	# s8
	.byte 0	# s8
	.byte 0	# s8
	.long 2	# s32
	.space 4	# pad
	.byte 4	# s8
	.byte 0	# s8
	.byte 0	# s8
	.byte 0	# s8
	.data
# -- End  main
	.data
	.align 4
EPC.RZERO.0:
	.long 0x00000000,0x00000000,0x00000000,0x00000000	# xf128
	.type	EPC.RZERO.0,@object
	.size	EPC.RZERO.0,16
	.data
# End

 credo che le differenze siano sensibili.
Anzichč usare clock() in C e l'equivalente in Fortran, un risultato
molto piů preciso si puň avere usando il comando time in questo modo:
time ./a.out
Fornisce statistiche piů accurate, ed inoltre č in grado di cronometrare
il tempo passato in chiamate al kernel (sys), il tempo totale e,
sopratutto, il tempo utente, cioč quello passato effettivamente nel
codice del tuo programma. Come avviene anche alle IOI, dovresti
guardare quello per avere un'idea del tempo impiegato dal codice in
maniera precisa.
-- 
Andrea Bergia - studente              Linux Registered User #281550

 [CUT]
Questo e' il ciclo eseguito 1.000.000.000 di volte.
1. aggiunge 5 al registro a 32bit eax
2. confronta il contenuto di eax con 1.000.000.000
3. se il confronto e' minore o uguale salta a ..B1.4
Perche' somma 5?
Dov'e' il mod?
Temo che ci sia qualche errore. Potrei aver letto male il codice 
assembler, ma direi che e' un altro programma.
Potrei capire la mancanza del mod: il compilatore vede che la variabile 
somma non viene usata dopo quell'istruzione per cui non la esegue 
proprio. Ma come puo' decidere di incrementare di 5 invece che di 1?
Potresti controllare?
Ciao.
  -Ema-

 
Era per evitare di aggiungere anche il tempo per l'inizializzazione del 
programma, eventuali stampe etc. Penso pero' che tu abbia ragione.
-=M=M=- stava facendo come hai detto tu. Sono stato io a suggerire 
l'approccio con il clock. Se guardi l'altro ramo pero' ho detto a 
-=M=M=- di ritornare a calcolare il tempo come hai detto tu.
Ciao.
  -Ema-


I tempi dati da time si riferiscono a tutto il programma e non ad una
sola porzione di esso, che e' quello che al momento interessava trovare.
 
 

 
No non ci sono errori e' proprio quello prodotto da compilatore e che io
ho compilato prima.
Faccio un test con un codice analogo, vediamo che succede
	program prova
	implicit none
	integer i
	integer z
	do i=1,10
	   z=mod(i,2)
	enddo
	stop
	end
compilo con ifc -S dove -S e':
-S         compile to assembly (.s) only, do not link (*I)
ed ottengo:
# -- Machine type IA32
# mark_description "Intel(R) Fortran Compiler for 32-bit applications, Version 7.1   Build 20030307Z";
# mark_description "-Xlinker -rpath -Xlinker /opt/intel/compiler70/ia32/lib -I/opt/intel/compiler70/ia32/include -S";
	.ident "Intel(R) Fortran Compiler for 32-bit applications, Version 7.1   Build 20030307Z"
	.ident "-Xlinker -rpath -Xlinker /opt/intel/compiler70/ia32/lib -I/opt/intel/compiler70/ia32/include -S"
	.file "prova.f"
	.text
	.data
	.align 4
	.bss
	.align 4
	.data
	.text
# -- Begin  main
# mark_begin;
       .align    4,0x90
	.globl main
main:
# parameter 1: 8 + %ebp
# parameter 2: 12 + %ebp
..B1.1:                         # Preds ..B1.0
        pushl     %ebp                                          #1.0
        movl      %esp, %ebp                                    #1.0
        subl      $3, %esp                                      #1.0
        andl      $-8, %esp                                     #1.0
        addl      $4, %esp                                      #1.0
        pushl     12(%ebp)                                      #1.0
        lea       8(%ebp), %eax                                 #1.0
        pushl     %eax                                          #1.0
        call      f90_init                                      #1.0
                                # LOE ebx esi edi
..B1.2:                         # Preds ..B1.1
        push      $0                                            #9.0
        push      $-1                                           #9.0
        call      f_stop                                        #9.0
                                # LOE ebx esi edi
..B1.3:                         # Preds ..B1.2
        addl      $16, %esp                                     #10.0
        movl      %ebp, %esp                                    #10.0
        popl      %ebp                                          #10.0
        xorl      %eax, %eax                                    #10.0
        ret                                                     #10.0
        .align    4,0x90
                                # LOE
# mark_end;
	.type	main,@function
	.size	main,.-main
	.data
# -- End  main
	.data
	.align 4
EPC.RZERO.0:
	.long 0x00000000,0x00000000,0x00000000,0x00000000	# xf128
	.type	EPC.RZERO.0,@object
	.size	EPC.RZERO.0,16
	.data
# End
Fa lo stesso giochetto di prima?

Codice:
        program prova
        implicit none
        integer max_cycles 
        integer somma,i
        real    t0,t1
 
        parameter (max_cycles=1000000000)
 
        somma = 0
        i = 0
 
        call cpu_time(t0)
 
        do i=1,max_cycles
                somma = mod((somma+i),999999)
        enddo
        call cpu_time(t1)
        write(*,*) 'tempo -> ',t1-t0    
 
        stop
        end
con ifc -S mi da:
# -- Machine type IA32
# mark_description "Intel(R) Fortran Compiler for 32-bit applications, Version 7.1   Build 20030307Z";
# mark_description "-Xlinker -rpath -Xlinker /opt/intel/compiler70/ia32/lib -I/opt/intel/compiler70/ia32/include -S";
	.ident "Intel(R) Fortran Compiler for 32-bit applications, Version 7.1   Build 20030307Z"
	.ident "-Xlinker -rpath -Xlinker /opt/intel/compiler70/ia32/lib -I/opt/intel/compiler70/ia32/include -S"
	.file "programmare.f"

                                # LOE eax ebx esi edi
..B1.4:                         # Preds ..B1.4 ..B1.3
        addl      $5, %eax                                      #18.0
        cmpl      $1000000000, %eax                             #18.0
        jle       ..B1.4        # Prob 100%                     #18.0
                                # LOE eax ebx esi edi


 
L'impressione e' che salti completamte il ciclo.
Prova a stampare alla fine il valore di z cosi' il compilatore e' 
costretto a calcolarlo veramente. E' solo un impressione, non ricordo 
abbastanza di assembler per averne la certezza.
Ciao.
  -Ema-

-=M=M=-@
cippa.lippa.net
 wrote:
 > ...B1.4:                         # Preds ..B1.4 ..B1.3
 >         addl      $5, %eax                                      #18.0
 >         cmpl      $1000000000, %eax                             #18.0
 >         jle       ..B1.4        # Prob 100%                     #18.0
 >                                 # LOE eax ebx esi edi
L'impressione e' che salti completamte il ciclo.
Prova a stampare alla fine il valore di z cosi' il compilatore e' 
costretto a calcolarlo veramente. E' solo un impressione, non ricordo 
abbastanza di assembler per averne la certezza.
Ho fatto un copia incolla dell'altra risposta :D
Ciao.
  -Ema-

Il Fri, 05 Sep 2003 19:25:50 GMT, -Ema- fece sapere che:

Dunque dunque...
============================ 
        program prova
        implicit none
        integer i
        integer z
        do i=1,10
           z=mod(i,2)
        enddo
        print *,z
        stop
        end
============================
che da:
:/tmp$ ifc programmare3.f
   program PROVA
11 Lines Compiled
:/tmp$ ./a.out
           0
Il che e' corretto dato che i=10 e mod(10,2) = 0, per sicurezza porto i
a 11
ed ottengo:
:/tmp$ ifc programmare3.f
   program PROVA
11 Lines Compiled
:/tmp$ ./a.out
           1
Che e' corretto, se vuoi posto pure il codice ASM, inizio a pensare,
(supponendo che la tua lettura del codice ASM sia corretta), che il
compilatore usi una qualche procedura ottimizzante per ridurra i tempi di
calcolo di mod().

Il Fri, 05 Sep 2003 19:29:57 GMT, -Ema- fece sapere che:

Dimenticavo di dirti che mod() a differenza del % del C e' una funzione
intrinseca del compilatore, e non un operatore, forse cio' che tu trovi
strano rigurada l'implementazione della funzione mod().
Ok vediamo allora, aggiunrgo un print per avere l'output
==========================================
        program prova
        implicit none
        integer max_cycles 
        integer somma,i
        real    t0,t1
 
        parameter (max_cycles=1000000000)
 
        somma = 0
        i = 0
 
        call cpu_time(t0)
 
        do i=1,max_cycles
                somma = mod((somma+i),999999)
                print *, somma, i
        enddo
        call cpu_time(t1)
        write(*,*) 'tempo -> ',t1-t0    
 
        stop
        end
========================================
se lo lancio ho :
	   1           1
           3           2
           6           3
          10           4
          15           5
          21           6
          28           7
          36           8
          45           9
          55          10
          66          11
          78          12
          91          13
         105          14
         120          15
         136          16
         153          17
         171          18
         190          19
         210          20
         231          21
         253          22
         276          23
         300          24
         325          25
         351          26
         378          27
         406          28
         435          29
         465          30
         496          31
         528          32
         561          33
[CUT]
il che mi pare che nel ciclo ci passi eccome :)
ASM prodotto e:
======================================

        pushl     %esi                                          #1.0
        pushl     %ebx                                          #1.0
        subl      $8, %esp                                      #1.0
        pushl     12(%ebp)                                      #1.0
        lea       8(%ebp), %eax                                 #1.0
        pushl     %eax                                          #1.0
        call      f90_init                                      #1.0
                                # LOE esi edi
..B1.2:                         # Preds ..B1.1
        lea       8(%esp), %eax                                 #14.0
        pushl     %eax                                          #14.0
        xorl      %ebx, %ebx                                    #11.0
        call      f90_cputime4                                  #14.0
                                # LOE ebx esi edi
..B1.18:                        # Preds ..B1.2
        addl      $12, %esp                                     #14.0
                                # LOE ebx esi edi
..B1.3:                         # Preds ..B1.18
        movl      $1, %eax                                      #16.0
        movl      %ebx, %esi                                    #16.0
        movl      %eax, %ebx                                    #16.0
        .align    4,0x90
                                # LOE ebx esi edi
..B1.4:                         # Preds ..B1.8 ..B1.3
        push      $mainIOTABLES.33+20                           #18.0
        addl      %ebx, %esi                                    #17.0
        movl      $1125901033, %eax                             #17.0
        imull     %esi                                          #17.0
        movl      %esi, %ecx                                    #17.0
        sarl      $31, %ecx                                     #17.0
        push      $0                                            #18.0
        sarl      $18, %edx                                     #17.0
        subl      %ecx, %edx                                    #17.0
        imull     $999999, %edx, %ecx                           #17.0
        subl      %ecx, %esi                                    #17.0
        call      f_iod                                         #18.0
                                # LOE ebx esi edi
..B1.5:                         # Preds ..B1.4
        push      $mainIOTABLES.33+32                           #18.0
        movl      %esi, mainIOTABLES.33+36                      #18.0
        push      $10                                           #18.0
        call      f_iod                                         #18.0
                                # LOE ebx esi edi
..B1.6:                         # Preds ..B1.5
        push      $mainIOTABLES.33+44                           #18.0
        movl      %ebx, mainIOTABLES.33+48                      #18.0
        push      $10                                           #18.0
        call      f_iod                                         #18.0
                                # LOE ebx esi edi
..B1.7:                         # Preds ..B1.6
        push      $0                                            #18.0
        push      $-1                                           #18.0
        call      f_iod                                         #18.0
                                # LOE ebx esi edi
..B1.19:                        # Preds ..B1.7
        addl      $32, %esp                                     #18.0
                                # LOE ebx esi edi
..B1.8:                         # Preds ..B1.19
        addl      $1, %ebx                                      #19.0
        cmpl      $1000000000, %ebx                             #19.0
        jle       ..B1.4        # Prob 100%                     #19.0
                                # LOE ebx esi edi
..B1.9:                         # Preds ..B1.8
        lea       4(%esp), %eax                                 #21.0
        pushl     %eax                                          #21.0
        call      f90_cputime4                                  #21.0
                                # LOE esi edi
..B1.10:                        # Preds ..B1.9
        push      $mainIOTABLES.33+60                           #23.0
        push      $0                                            #23.0
        call      f_iod                                         #23.0
                                # LOE esi edi
..B1.11:                        # Preds ..B1.10
        movl      $mainSST.32, mainIOTABLES.33+76               #23.0
        push      $mainIOTABLES.33+72                           #23.0
        push      $11                                           #23.0
        call      f_iod                                         #23.0
                                # LOE esi edi
..B1.12:                        # Preds ..B1.11
        flds      24(%esp)                                      #23.0
        fsubs     20(%esp)                                      #23.0
        fstps     EPC_GLA34                                     #23.0
        movl      $EPC_GLA34, mainIOTABLES.33+88                #23.0
        push      $mainIOTABLES.33+84                           #23.0
        push      $11                                           #23.0
        call      f_iod                                         #23.0
                                # LOE esi edi
..B1.13:                        # Preds ..B1.12
        push      $0                                            #23.0
        push      $-1                                           #23.0
        call      f_iod                                         #23.0
                                # LOE esi edi
..B1.14:                        # Preds ..B1.13
        push      $0                                            #25.0
        push      $-1                                           #25.0
        call      f_stop                                        #25.0
                                # LOE esi edi
..B1.15:                        # Preds ..B1.14
        addl      $52, %esp                                     #26.0
        popl      %ebx                                          #26.0
        popl      %esi                                          #26.0
        movl      %ebp, %esp                                    #26.0
        popl      %ebp                                          #26.0
        xorl      %eax, %eax                                    #26.0
        ret                                                     #26.0
        .align    4,0x90
                                # LOE
# mark_end;
	.type	main,@function
	.size	main,.-main
	.bss
	.align 4
EPC_GLA34:
	.type	EPC_GLA34,@object
	.size	EPC_GLA34,4
	.space 4	# pad
	.data
	.align 32
mainIOTABLES.33:
	.byte 12	# s8
	.byte 109	# s8
	.byte 97	# s8
	.byte 105	# s8
	.byte 110	# s8
	.byte 32	# s8
	.byte 112	# s8
	.byte 114	# s8
	.byte 111	# s8
	.byte 103	# s8
	.byte 114	# s8
	.byte 97	# s8
	.byte 109	# s8
	.space 3	# pad
	.long 1179668	# s32
	.long 6	# s32
	.byte 3	# s8
	.byte 0	# s8
	.byte 98	# s8
	.byte 0	# s8
	.space 4	# pad
	.long 1	# s32
	.space 4	# pad
	.long 4	# s32
	.long 1	# s32
	.space 4	# pad
	.long 4	# s32
	.long 1507388	# s32
	.long 6	# s32
	.byte 3	# s8
	.byte 0	# s8
	.byte 98	# s8
	.byte 0	# s8
	.space 4	# pad
	.long 5	# s32
	.space 4	# pad
	.byte 9	# s8
	.byte 0	# s8
	.byte 0	# s8
	.byte 0	# s8
	.long 2	# s32
	.space 4	# pad
	.byte 4	# s8
	.byte 0	# s8
	.byte 0	# s8
	.byte 0	# s8
mainSST.32:
	.byte 116	# s8
	.byte 101	# s8
	.byte 109	# s8
	.byte 112	# s8
	.byte 111	# s8
	.byte 32	# s8
	.byte 45	# s8
	.byte 62	# s8
	.byte 32	# s8
	.data
# -- End  main
	.data
	.align 32


 ========================================
Scusa, mi sono spiegato molto male. Il print e' sufficiente metterlo 
alla fine. Alla fine di tutti e due i programmi assieme al print del 
tempo. Anzi, poiche' mi sento in colpa visto che i tests li fai tutti 
tu, ora mi scarico il compilatore fortran95 di intel, faccio le 
modifiche ed i test. Poi ti faccio sapere.
Comunque ora nel ciclo c'e':
..B1.4:                         # Preds ..B1.8 ..B1.3
         push      $mainIOTABLES.33+20                           #18.0
         addl      %ebx, %esi                                    #17.0
         movl      $1125901033, %eax                             #17.0
         imull     %esi                                          #17.0
         movl      %esi, %ecx                                    #17.0
         sarl      $31, %ecx                                     #17.0
         push      $0                                            #18.0
         sarl      $18, %edx                                     #17.0
         subl      %ecx, %edx                                    #17.0
         *imull     $999999, %edx, %ecx                           #17.0*
         subl      %ecx, %esi                                    #17.0
         call      f_iod                                         #18.0
                                 # LOE ebx esi edi
..B1.5:                         # Preds ..B1.4
         push      $mainIOTABLES.33+32                           #18.0
         movl      %esi, mainIOTABLES.33+36                      #18.0
         push      $10                                           #18.0
         call      f_iod                                         #18.0
                                 # LOE ebx esi edi
..B1.6:                         # Preds ..B1.5
         push      $mainIOTABLES.33+44                           #18.0
         movl      %ebx, mainIOTABLES.33+48                      #18.0
         push      $10                                           #18.0
         call      f_iod                                         #18.0
                                 # LOE ebx esi edi
..B1.7:                         # Preds ..B1.6
         push      $0                                            #18.0
         push      $-1                                           #18.0
         call      f_iod                                         #18.0
                                 # LOE ebx esi edi
..B1.19:                        # Preds ..B1.7
         addl      $32, %esp                                     #18.0
                                 # LOE ebx esi edi
..B1.8:                         # Preds ..B1.19
         *addl      $1, %ebx                                      #19.0*
         cmpl      $1000000000, %ebx                             #19.0
         jle       ..B1.4        # Prob 100%                     #19.0
                                 # LOE ebx esi edi
in cui si trova l'operazione di modulo e l'incremento di 1.
Ciao.
  -Ema-

 
Si ho capito cosa intendevi ed ecco cosa accade:
:/tmp$ ./a.out 
      500500
 tempo ->    25.38000 
Ummhhh ma che fa mi prende in giro? :)
Qundi la variabile viene usata in un qualcosa, esegue il loop,
altrimenti fai dei calcoli forfettari?
Mhhh faccio un'altra prova, al posto di "write(*,*) somma" posto dopo il
ciclo metto un somma = somma+1
===============================
        program prova
        implicit none
        integer max_cycles 
        integer somma,i
        real    t0,t1
 
        parameter (max_cycles=1000000000)
 
        somma = 0
        i = 0
 
        call cpu_time(t0)
 
        do i=1,max_cycles
                somma = mod((somma+i),999999)
C               print *, somma, i
        enddo
        call cpu_time(t1)
        !write(*,*) somma
        somma = somma +1
        write(*,*) 'tempo -> ',t1-t0    
 
        stop
        end
========================================
e nuovamente mi da :
:/tmp$ ./a.out 
 tempo ->    1.020000   
mmmhhh che sia un BUG del compilatore?
Credo che mandero' un post su com.lang.fortran dove c'e' gente veramente
preparata.
Cmq almabench lo hai letto?

 
Gli ho appena dato un occhiata. Se ci riesco controllo anche i sorgenti.
E' interessante. Si parla sempre di applicazioni numeriche ovviamente.
Ciao.
  -Ema-

 E' interessante. Si parla sempre di applicazioni numeriche ovviamente.
Certo, tolte le applicazioni numeriche Fortran non serve a nulla :)

 funzione specile, keyword o altro.
Allora ho appena ricevuto le risposte da comp.lang.fortran
Il fatto che impieghi 1 oppure 24 secondi dipende dal fatto che il
compilatore si accorge che la variabile e il ciclo non interagiscono con
altre parti di programma quindi *salta* le istruzioni in un qualche
modo, il che mi pare buono ne caso rimangano rimasugli di codice inutile
in un progetto.
Ma ora veniamo al pezzo forte :) ho chiesto di ottimizzare il codice, e
mi hanno fornito un sorgente ottimizzato, beh se prima 1 secondo (seppur
errato) era incredibile ora si va oltre ogni cosa nota ;)
Non per merito del linguaggio, ma grazie al programmatore :)
guarda:
======================== 
          program test
          implicit none
          integer max_cycles,N
          integer sums,i,j
          real    t0,t1
          parameter (max_cycles=1000000000)
	  parameter (N=999999)
          sums = 0
          j=mod(max_cycles,N)
          call cpu_time(t0)
          do i=1,j
           sums=mod(sums+i,N)
          enddo
          call cpu_time(t1)
          write(*,*) sums,j
C         sums = sums +1
          write(*,*) 'time -> ',t1-t0
          stop
        end
=============================
$ ifc fortran.f -o fortran
   program TEST
27 Lines Compiled
$ ./fortran
      500500        1000
 time ->    0.000000E+00
Alla faccia di chi so io :) 
Ciauz

  time ->    0.000000E+00
corro in soffita a ritirar giu' il manuale di fortran!!!
-- 
(setq RiK0 "Enrico Franchi")
(setq url "
www.anubics.org
")
(setq quote "Se mi prendo sul serio, 
 c'e' da mettersi a ridere." )

 in un progetto.
Si. Dimostra la bonta' del compilatore. Penso pero' che ci porti fuori 
strada. In un certo senso sta applicando le ottimizzazioni che ci 
eravamo prefissi di non utilizzare. Il fatto e' che noi non utilizziamo 
il valore calcolato perche' si tratta di un test e non di un programma 
effettivo. Se fossimo in un programma vero il risultato lo useremmo 
oppure butteremmo via il codice che lo produce.
Direi che per il momento il tempo di esecuzione e' di ~24 secondi.

Non puoi cambiare algoritmo. In questo modo esegui il ciclo solo 1000 
volte. Complimenti a chi ha applicato l'equivalenza, che dimostra la sua 
bravura ma non la velocita' del fortran. Infatti se applichiamo la 
stessa soluzione al sorgente C otteniamo anche con questo un risultato 
non piu' misurabile.
====================================================
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define MAX_CYCLES 1000000000
#define N 999999
int main() {
         clock_t c;
         clock_t d;
         register int sum = 0;
         register int i = 0;
         int j = MAX_CYCLES % N;
         printf( "N. cycles %d\n", j );
         c = clock();
         for( i = 1; i <= j; i++ )
                 sum = ( sum + i ) % N;
         d = clock() - c;
         printf( "sum=%d, j=%d\n", sum, j );
         printf( "It tooks %f to performs\n", ( float ) d / (float) 
CLOCKS_PER_SEC );
         return 0;
}
====================================================
Per ottimizzazioni intendevo l'utilizzo di una funzione modulo per 
numeri interi a 32 bit o cose di questo tipo.
Se ci mettiamo a confrontare le prestazioni in termini di velocita' di 
esecuzione di due linguaggi per l'esecuzione di un ordinamento non 
possiamo utilizzare per uno il bubblesort e per l'altro il quicksort.
IMHO per il momento il tempo resta ~24 sec per il fortran e ~11 sec per 
il C. Cosa ne pensi tu? So che ti rode ma per il momento devi ammetterlo 
:-).
Ciao.
  -Ema-
P.S. Prego chi leggesse solo questo post di non interpretare le prove 
che stiamo facendo io e -=M=M=- come un modo per stabilire quale 
linguaggio sia migliore. E' un gioco fatto su un solo esempio che non ha 
la benche' minima pretesa di dire alcunche'.

 la benche' minima pretesa di dire alcunche'.
Infatti, pero' il thread e' stato interessante seppur inutile, almeno io
la penso cosi'

 corro in soffita a ritirar giu' il manuale di fortran!!!
Veramente e' tutto merito del programmatore che ha messo mano al codice
non del linguaggio.
Per la soffitta lascia perdere il fortran77 e' totalmente diverso dal
fortran95 (attualmente sviluppato), in rete trovi molta roba a proposito
Un buon punto di inizio e' 
www.fortran.com