PDA

Visualizza la versione completa : [C] Benchmark sulle funzioni


/dev/null
05-09-2004, 04:26
So che col C eseguire una funzione richiede piu' tempo (si parla di millesimi di secondi, ovviamente) che eseguire il codice nella funzione corrente...
Volevo fare un benchmark per vedere quanto fosse questo tempo e l'ho fatto :zizi:
Ma i risultati m'hanno lasciato stupefatto :oVVoVe:

Ho fatto un programmino che esegue un miliardo di cicli... Una volta lo fa senza fare niente al loro interno, soltanto incrementando una variabile... La seconda volta invece richiama una funzione void che non fa niente di niente, non prende parametri e non restituisce valore...

Ecco i risultati:
dewell@myamd bench $ ./cfunctions
Tempo impiegato per eseguire 1000000000 cicli eseguendo ogni volta una funzione vuota: 49 secondi.
dewell@myamd bench $ ./cfunctions x
Tempo impiegato per eseguire 1000000000 cicli senza eseguire ogni volta una funzione vuota: 3 secondi.

:oVVoVe:




Se volete il codice per eseguire questo test sulle vostre macchine compilando il programma con altri compilatori (io ho usato il GCC) eccovi il codice:
#include <stdio.h>
#include <time.h>

#define LOOPS 1000000000

void use_func ( );
void not_use_func ( );
void func ( );
void usage ( char * progname );

int main ( int argc, char * argv [] ) {

if ( argc == 1 )
use_func ( );
else if ( argc == 2 )
not_use_func ( );
else
usage ( argv[0] );

return 0;
}

void use_func ( ) {
time_t start;
time_t end;
int i;

start = time ( NULL );
for ( i = 0; i < LOOPS; i ++ )
func ( );
end = time ( NULL );

printf ( "Tempo impiegato per eseguire %d cicli eseguendo ogni volta una funzione vuota: %d secondi.\n",
LOOPS, (int) ( end - start ) );
}

void not_use_func ( ) {
time_t start;
time_t end;
int i;

start = time ( NULL );
for ( i = 0; i < LOOPS; i ++ );
end = time ( NULL );

printf ( "Tempo impiegato per eseguire %d cicli senza eseguire ogni volta una funzione vuota: %d secondi.\n",
LOOPS, (int) ( end - start ) );
}

void func ( ) {
}

void usage ( char * progname ) {
printf ( "Utilizzo: `%s': verra' eseguita alcuna funzione vuota per ogni loop del ciclo.\n"
" `%s *': non verra' eseguita alcuna funzione vuota per ogni loop del ciclo.\n",
progname, progname );
}








Ho anche un'altra domanda...
Il GCC permette di dichiarare alcune funzioni usando la direttiva inline col C, che con gli altri compilatori non dovrebbe essere presente poiche' e' una direttiva standard del C++, ma non presente nel C...
Per chi non sa cosa sia, la direttiva inline dovrebbe trasformare la funzione in una macro: dovrebbe cioe' sostituire i richiami alla funzione con il codice della funzione per velocizzarne il codice...
Ho provato a dichiarare inline la funzione func(), ma ottengo sempre gli stessi identici valori :fagiano:
Sapreste spigarmi il motivo? Il GCC accetta la direttiva inline, ma non la utilizza? :fagiano:


:ciauz:

Luc@s
05-09-2004, 10:11
Originariamente inviato da /dev/null

Sapreste spigarmi il motivo? Il GCC accetta la direttiva inline, ma non la utilizza? :fagiano:


Il Gcc prima del supporto al c99 accettava un suo inlone built-in.
Ora, supportanto il c99, supporta inline ma dato che inline è un consiglio al compilatore(che puo nn essere seguito)...

/dev/null
05-09-2004, 11:07
Originariamente inviato da Luc@s
inline è un consiglio al compilatore(che puo nn essere seguito)... Ne sei sicuro? :dottò:
Onestamente io sapevo che altre direttive tipo "register" sono consigli al compilatore, ma inline e' un obbligo!
Sul manuale che ho usato per studiare il C c'e' scritto che creare una macro con #define e' esattamente identico a creare una funzione inline :bhò:

Luc@s
05-09-2004, 11:10
Syntax
1 function-specifier:
inline
Constraints
2 Function specifiers shall be used only in the declaration of an identifier for a function.
3 An inline definition of a function with external linkage shall not contain a definition of a
modifiable object with static storage duration, and shall not contain a reference to an
identifier with internal linkage.
4 In a hosted environment, the inline function specifier shall not appear in a declaration
of main.
Semantics
5 A function declared with an inline function specifier is an inline function. The
function specifier may appear more than once; the behavior is the same as if it appeared
only once. Making a function an inline function suggests that calls to the function be as
fast as possible.118) The extent to which such suggestions are effective is
implementation-defined.119)
6 Any function with internal linkage can be an inline function. For a function with external
linkage, the following restrictions apply: If a function is declared with an inline
118) By using, for example, an alternative to the usual function call mechanism, such as ‘‘inline
substitution’’. Inline substitution is not textual substitution, nor does it create a new function.
Therefore, for example, the expansion of a macro used within the body of the function uses the
definition it had at the point the function body appears, and not where the function is called; and
identifiers refer to the declarations in scope where the body occurs. Likewise, the function has a
single address, regardless of the number of inline definitions that occur in addition to the external
definition.
119) For example, an implementation might never perform inline substitution, or might only perform inline
substitutions to calls in the scope of an inline declaration.
112 Language §6.7.4
©ISO/IEC ISO/IEC 9899:1999 (E)
function specifier, then it shall also be defined in the same translation unit. If all of the
file scope declarations for a function in a translation unit include the inline function
specifier without extern, then the definition in that translation unit is an inline
definition. An inline definition does not provide an external definition for the function,
and does not forbid an external definition in another translation unit. An inline definition
provides an alternative to an external definition, which a translator may use to implement
any call to the function in the same translation unit. It is unspecified whether a call to the
function uses the inline definition or the external definition.120)
7 EXAMPLE The declaration of an inline function with external linkage can result in either an external
definition, or a definition available for use only within the translation unit. A file scope declaration with
extern creates an external definition. The following example shows an entire translation unit.
inline double fahr(double t)
{
return (9.0 * t) / 5.0 + 32.0;
}
inline double cels(double t)
{
return (5.0 * (t - 32.0)) / 9.0;
}
extern double fahr(double); // creates an external definition
double convert(int is_fahr, double temp)
{
/* A translator may perform inline substitutions */
return is_fahr ? cels(temp) : fahr(temp);
}
8 Note that the definition of fahr is an external definition because fahr is also declared with extern, but
the definition of cels is an inline definition. Because cels has external linkage and is referenced, an
external definition has to appear in another translation unit (see 6.9); the inline definition and the external
definition are distinct and either may be used for the call.


Estratto dal documento dello standard C99

/dev/null
05-09-2004, 11:25
Originariamente inviato da Luc@s
Estratto dal documento dello standard C99 Ok :stordita:



Allora credo che non usero' mai piu' inline, ma mi affidero' alle macro :bhò:

Luc@s
05-09-2004, 11:28
Originariamente inviato da /dev/null

Allora credo che non usero' mai piu' inline, ma mi affidero' alle macro :bhò:

Le macro nn sono sempre il max in tutto......e epr il debug sono la morte neuronale :(

/dev/null
05-09-2004, 11:37
Originariamente inviato da Luc@s
Le macro nn sono sempre il max in tutto......e epr il debug sono la morte neuronale :( Si' purtroppo e' vero, hanno moltissimi problemi...
Tanto per fare un esempio... Se ho la macro:
#define POWER(n) (n*n)
E la volessi usare per calcolare la potenza di X incrementato non posso fare:
POWER ( X ++ );
:cry:
tuttavia usero' le macro (fin'ora ho usato le funzioni inline) solo per definire un paio di righe di codice...
Riguardo al debug... Ci faro' piu' attenzione :fagiano:

Richiamare una funzione in un ciclo che verra' ripetuto milioni di volte mi sembra alquanto distruttivo... :fagiano:

Ikitt
05-09-2004, 18:43
Originariamente inviato da /dev/null

Richiamare una funzione in un ciclo che verra' ripetuto milioni di volte mi sembra alquanto distruttivo... :fagiano:

...E` per questo che hanno inventato le funzioni inline :D

Gen.Web
05-09-2004, 19:11
ho provato anche io quel programma con mingw....
18 secondi con la funzione
3 secondi senza funzione

HO provato a mettere inline a func ma ho ottenuto sempre 18 secondi :messner:
Probabilmente in questa situazione il compilatore non ritiene che sia conveniente eseguire la funzione inline

iguana13
05-09-2004, 19:15
Un compilatore con molte ottimizzazioni anche ti direbbe che la funzione è perfettamente inutile :stordita:

Loading