Jump to content

Recommended Posts

Posted

Boas pessoal,

Estou a tentar otimizar um projecto em C, so que tenho uma duvida:

posso calcular o tempo do projecto todo fazendo "time ./nomeProjecto" no terminal, contudo existe alguma maneira de saber quanto tempo gasta cada função desse mesmo projecto, para ver onde gasta mais tempo?

Agradeço desda ja a disponibilidade

Posted

Podes usar o clock da tua máquina para calcular esse tempo:


#include <time.h>

definição da tua função {

clock_t ini = clock(); // guardas o inicial

 // Código da função

 // Mostra a contagem do clock actual menos o valor inicial.. Divides pelo tempo que cada ciclo demora em segundos para obteres o tempo total em segundos
printf("\nFuncao executou em %f segundos\n", ((double)clock() - ini) / CLOCKS_PER_SEC);

}

Posted (edited)

Eu costumo usar o profiler gprof (exemplo abaixo).

Outra opcao é meteres o programa no debugger e examinares o call stack algumas vezes. A função que mais vezes está no topo é a função que gasta mais tempo.

Podes ainda escrever código para medir o tempo de cada função, mas isso implica alterar o código fonte.

Podes usar o clock da tua máquina para calcular esse tempo:

Correcto.

Mas o clock tem uma resolução pequena: para obteres resultados usaveis com programas 'rápidos' precisas de correr o programa milhões de vezes.

Tendo um sistema que suporta POSIX, é mais preciso usar as funções clock_*. Windows também tem funções que calculam o tempo com grande resolução, mas não as sei de cor -- e não tou para pesquisar 🙂


Exemplo do gprof com o seguinte codigo para calcular a soma de digitos dum numero

/* soma de digitos */

#include <stdio.h>

unsigned um(unsigned k) {
 /* converte para string */
 char tmp[1000], *p;
 unsigned val = 0;

 sprintf(tmp, "%d", k);
 p = tmp;
 while (*p) {
   val += *p - '0';
   p++;
 }
 return val;
}

unsigned dois(unsigned k) {
 /* divisoes sucessivas */
 unsigned val = 0;
 while (k) {
   val += k % 10;
   k /= 10;
 }
 return val;
}

int main(void) {
 unsigned k;
 for (k = 0; k < 100000; k++) {
   if (um(k) != dois(k)) printf("erro para o valor %d.\n", k);
 }
 return 0;
}

Compilei com o gcc, sem optimizacoes e com a opcao de gerar informacao para o gprof

$ gcc -std=c89 -pedantic -Wall -Werror -O0 -pg sod.c

Corro o programa para gerar informações para o profiler

$ ./a.out

E agora, que já tenho o ficheiro gmon.out, posso chamar o profiler e estudar o resultado

$ gprof
Flat profile:

Each sample counts as 0.01 seconds.
no time accumulated

 %   cumulative   self              self     total
time   seconds   seconds    calls  Ts/call  Ts/call  name
100.95      0.01     0.01   100000   100.95   100.95  um
 0.00      0.01     0.00   100000     0.00     0.00  dois

%         the percentage of the total running time of the
time       program used by this function.

... ...

                    Call graph (explanation follows)


granularity: each sample hit covers 2 byte(s) no time propagated

index % time    self  children    called     name
               0.01    0.00  100000/100000      main [2]
[1]    100.0    0.01    0.00  100000         um [1]
-----------------------------------------------
                                                <spontaneous>
[2]    100.0    0.00    0.01                 main [2]
               0.01    0.00  100000/100000      um [1]
               0.00    0.00  100000/100000      dois [3]
-----------------------------------------------
               0.00    0.00  100000/100000      main [2]
[3]      0.0    0.00    0.00  100000         dois [3]
-----------------------------------------------

This table describes the call tree of the program, and was sorted by
the total amount of time spent in each function and its children.

... ... ... ...

Donde se pode facilmente ver que a funcao um() ocupa o tempo todo 🙂

Edited by pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted (edited)

Eu costumo usar o profiler gprof (exemplo abaixo).

Obrigado pela ajuda, contudo, quando faço:

"gprof projecto > projecto.tempo" no terminal do linux, da-me este erro:

"gmon.out: No such file or directory"

e eu compilei da seguinte forma: "gcc -o projectoLI -pg projectoLI.c"

Sabes se preciso de instalalar alguma coisa ou estou a fazer alguma coisa de mal?

Edited by pmg
nao era preciso o quote todo
Posted (edited)

Tens que correr o programa compilado com a opção -pg para gerar o gmon.out.

Faz

$ gcc -Wall -Werror -o projectoLI -pg projectoLI.c

$ ./projectoLI

$ gprof > projecto.tempo

Atenção que o programa demora muito mais tempo a executar quando compilado com -pg

Edited by pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.