Medir tempo de execução em C?

1,883 views
Skip to first unread message

Labaki

unread,
Dec 15, 2008, 2:22:54 PM12/15/08
to gpub...@googlegroups.com
Olá, turma!

Alguém conhece alguma função em C para medir tempo
de execução em milisegundos? A maioria das funções do
tipo só dá o tempo em segundos...

Sei que o CUDA tem uma função para medir tempo as-
sim, mas preciso de uma função em C puro (pra poder
comparar meu programa em C com o programa GPU).

Abraço!

~
J. Labaki
Laboratório de Mecânica Estrutural Computacional
Departamento de Mecânica Computacional
Faculdade de Engenharia Mecânica
Unicamp - Campinas/SP
http://www.jlabaki.com & http://www.gpubrasil.com

"Todos começam com um saco vazio de experiência e um saco cheio de sorte.
O segredo é encher o saco da experiência sem esvaziar o da sorte..."
-- Seleções de Reader's Digest.

Kelligton Neves

unread,
Dec 16, 2008, 7:05:17 AM12/16/08
to gpub...@googlegroups.com
Opá! Olá...

Já deu uma olhada nas funções QueryPerformanceFrequency(); e QueryPerformanceCounter();
Não tenho certeza se elas são c ou c++... Faz um tempo q as usei.

Kelligton



2008/12/15 Labaki <lab...@fem.unicamp.br>

Labaki

unread,
Dec 16, 2008, 10:22:56 AM12/16/08
to gpub...@googlegroups.com
2008/12/16 Kelligton Neves <kne...@gmail.com>:

> Opá! Olá...
>
> Já deu uma olhada nas funções QueryPerformanceFrequency(); e
> QueryPerformanceCounter();
> Não tenho certeza se elas são c ou c++... Faz um tempo q as usei.

Olá, Kelligton! Tudo bem com vc?

Bem-vindo à lista! Vc é o primeiro participante externo, fora da
nossa turma de GPU! Espero que seja o primeiro de muitos!
Como vc descobriu nosso site e nossa lista?

Pesquisei essas funções que você sugeriu, mas elas só funci-
onam com Windows... Vc tem alguma sugestão para Linux?

Kelligton Neves

unread,
Dec 16, 2008, 10:39:56 AM12/16/08
to gpub...@googlegroups.com
2008/12/16 Labaki <lab...@fem.unicamp.br>

2008/12/16 Kelligton Neves <kne...@gmail.com>:
> Opá! Olá...
>
> Já deu uma olhada nas funções QueryPerformanceFrequency(); e
> QueryPerformanceCounter();
> Não tenho certeza se elas são c ou c++... Faz um tempo q as usei.

Olá, Kelligton! Tudo bem com vc?

Opá... Olá! Td ótimo, e vc?
 

Bem-vindo à lista! Vc é o primeiro participante externo, fora da
nossa turma de GPU!   Espero que seja o primeiro de muitos!

Obrigado!
 

Como vc descobriu nosso site e nossa lista?

A lista foi divulgada no blog de um amigo meu e ele me repassou...

Acho legal me apresentar... Estudo Ciência da Computação (7º período) na Católica de Goias, moro atualmente em Goiânia e estou iniciando no mundo Cuda. Faço iniciaçao cientifica na Federal daqui, na area de processamento paralelo e, por isso estou começando estudar a linguagem.
 
Espero poder contar com vcs na hora do aperto. hehe... assim como vcs podem contar comigo no que eu puder ser útil.


Pesquisei essas funções que você sugeriu, mas elas só funci-
onam com Windows... Vc tem alguma sugestão para Linux?

Xiii... this is bad! Vou dar uma pesquisada, se encontrar algo eu posto aqui.
 

Abraço!

Outro!

Kelligton Neves

unread,
Dec 16, 2008, 10:50:35 AM12/16/08
to gpub...@googlegroups.com
Labaki,

Encontrei a funçao gettimeofday, ela permite trabalhar na casa dos microsegundos.

Não testei pq estou no serviço e aq é rwindows... :(
Sempre sobra merda pro estágiario. lol

Um exemplo rápido...
#include <sys/time.h>

struct timeval startTime, endTime;
struct timezone tz;
gettimeofday(&startTime, &tz);
gettimeofday(&endTime, &tz);

startTime.tv_sec // number of seconds since some epoch
startTime.tv_usec // number of microseconds since last second.


Just subtract the startTime from the endTime and you can get at least sufficient precision.

Referência:
http://www.opengroup.org/onlinepubs/000095399/functions/gettimeofday.html

2008/12/16 Kelligton Neves <kne...@gmail.com>

Henrique Fagundes Gasparoto

unread,
Dec 16, 2008, 11:04:09 AM12/16/08
to gpub...@googlegroups.com
Boa tarde Labaki.

Acredito que seja interessante você tentar utilizar a função clock() em conjunto com a macro CLOCKS_PER_SEC.

A função clock() retorna quantos ciclos de máquina se passaram desde o início do programa.
A macro CLOCKS_PER_SEC retorna o valor clocks / segundo da sua máquina.
Com isto você pode:

- Ler o retorno da função clock() em momentos de interesse no programa;
- Verificar quantos pulsos de clock se passaram entre estas leituras;
- Realizar uma divisão float entre esta diferença e o retorno da macro CLOCKS_PER_SEC;
- Multiplicar o resultado desta divisão por 1.000 e encontrar o valor em milisegundos.

Ainda não verifiquei a validade desta idéia, mas pretendo resolver este problema no código a ser rodado na CPU, desta forma.

Não se esqueça de incluir no cabeçalho o arquivo time.h.

Vou tentar implementar esta idéia por aqui.

Se tentar implementar comunique os resultados.

Um abraço!

Henrique Gasparoto.



2008/12/15 Labaki <lab...@fem.unicamp.br>

Labaki

unread,
Dec 17, 2008, 11:23:19 AM12/17/08
to gpub...@googlegroups.com
2008/12/16 Henrique Fagundes Gasparoto <henrique....@gmail.com>:

> Boa tarde Labaki.
>
> Acredito que seja interessante você tentar utilizar a função clock() em
> conjunto com a macro CLOCKS_PER_SEC.

Folks,

Eis a solução que achei para medir o tempo: uso as mesmas funções
que uso em programas do CUDA! hehehe Como não pensei nisso an-
tes? Em suma, meu programa em C é um programa CUDA, com a di-
ferença que nenhum kernel será executado, só funções em C. :P

É uma solução meio corinthiana, mas uma vez que o sou, beleza! :o)

Meu programa em C fica assim, então:

# include <cutil.h>

int main() {

unsigned int timer = 0;
CUT_SAFE_CALL(cutCreateTimer(&timer));
CUT_SAFE_CALL(cutStartTimer(timer));

// blablabla

printf("Tempo decorrido: %f \n",cutGetTimerValue(timer));

CUT_SAFE_CALL(cutDeleteTimer(timer));
}

Fácil, né?

A vantagem é que quando eu for comparar o tempo de execução desse
programa com um programa em CUDA, terei certeza de que a compara-
ção vai ser justa porque é o mesmo contador de tempo.

A desvantagem é que, além de salvar esse código C como .cu, tenho
que usar um "make" só para poder compilá-lo...

Agora só falta descobrir porque meu programa C está mais rápido que o
programa pra GPU... :'( Mas isso é outra estória.

Obrigado a todos pela ajuda!

Kelligton Neves

unread,
Dec 17, 2008, 12:20:42 PM12/17/08
to gpub...@googlegroups.com
lol...

Boa solução!

O programa em C está mais rápido!? Está emulando?

2008/12/17 Labaki <lab...@fem.unicamp.br>

Labaki

unread,
Dec 18, 2008, 1:53:41 PM12/18/08
to gpub...@googlegroups.com
2008/12/17 Kelligton Neves <kne...@gmail.com>:

> lol...
>
> Boa solução!
>
> O programa em C está mais rápido!? Está emulando?

O pior é que não... Estou rodando na placa, mesmo. O programa em C
leva em torno de 0,05 milissegundos, enquanto o da GPU leva em torno
de 30 milissegundos (é isso mesmo, 600 vezes mais rápido).

O Prof. Luiz Otávio disse que consigo um desempenho cerca de 600 ve-
zes melhor se eu passar minhas variáveis pra memória compartilhada,
em vez de usar a memória global como uso hoje. Talvez esse seja o pro-
blema. Assim que eu descobrir como se faz isso vou experimentar.

E seu problema com o emulador, resolveu?

Abraço!

Kelligton Neves

unread,
Dec 18, 2008, 3:38:22 PM12/18/08
to gpub...@googlegroups.com

2008/12/18 Labaki <lab...@fem.unicamp.br>


2008/12/17 Kelligton Neves <kne...@gmail.com>:
> lol...
>
> Boa solução!
>
> O programa em C está mais rápido!? Está emulando?

O pior é que não... Estou rodando na placa, mesmo. O programa em C
leva em torno de 0,05 milissegundos, enquanto o da GPU leva em torno
de 30 milissegundos (é isso mesmo, 600 vezes mais rápido).

Putz! Muita coisa mesmo...

O Prof. Luiz Otávio disse que consigo um desempenho cerca de 600 ve-
zes melhor se eu passar minhas variáveis pra memória compartilhada,
em vez de usar a memória global como uso hoje. Talvez esse seja o pro-
blema. Assim que eu descobrir como se faz isso vou experimentar.

Se conseguir, posta aq.

E seu problema com o emulador, resolveu?

Nao, ainda nao! TO na mesma... Vou instalar o 7.10 e tentar pra ver.

Labaki

unread,
Dec 20, 2008, 5:11:33 AM12/20/08
to gpub...@googlegroups.com
>> > O programa em C está mais rápido!? Está emulando?
>>
>> O pior é que não... Estou rodando na placa, mesmo. O programa em C
>> leva em torno de 0,05 milissegundos, enquanto o da GPU leva em torno
>> de 30 milissegundos (é isso mesmo, 600 vezes mais rápido).
>
> Putz! Muita coisa mesmo...
>>
>> O Prof. Luiz Otávio disse que consigo um desempenho cerca de 600 ve-
>> zes melhor se eu passar minhas variáveis pra memória compartilhada,
>> em vez de usar a memória global como uso hoje. Talvez esse seja o pro-
>> blema. Assim que eu descobrir como se faz isso vou experimentar.

Folks,

Era isso mesmo! heheheheh Passei somente dois vetores pra memória
compartilhada, e a GPU passou de 600 vezes mais lenta para 3 vezes
mais rápida. :) Acho que isso prova o tal custo de comunicação da GPU,
que é algo a ser evitado.

Daniel Medina

unread,
Feb 27, 2009, 7:14:15 AM2/27/09
to gpub...@googlegroups.com
Pessoal, já faz algum tempo que estou para reviver este tópico e sempre esqueço. Quero compartilhar com vocês um detalhe que me consumiu alguns dias quebrando a cabeça em cima disso.
 
Ao implementar em meu programa o algoritmo sugerido pelo Labaki para realizar a análise do tempo de execução, notei que o desempenho da GPU estava muito ruim comparado ao da CPU (com volume pequeno de dados estava até maior). Após procurar muito a causa, descobri que o vilão da história é a API do CUDA. Esta camada de software não é inicializada durante a inicialização do programa principal. Ela só é instanciada no momento da primeira chamada a alguma função da API (no meu caso ocorria quando eu chamava a função cuda_malloc pela primeira vez).
 
Ao receber a primeira instrução, a API se inicializa e isto leva um tempo considerável. Empiricamente levantei que esse tempo é de aproximadamente 40ms em uma 280 GTX e 70ms em uma 8800GT.
 
Para aplicações que duram dias ou semanas, este tempo não chega a ser um problema, mas para aplicações como a minha, cujo tempo de execução é da ordem de milissegundos, este delay é algo altamente indesejável.
 
Como solução, eu coloquei uma instrução "dummy" (malloc de 0 bytes) no início do algoritmo só para inicializar a placa, e desconsiderei este tempo do cálculo utilizado para comparação entre CPU e GPU, pois acredito que por ser um custo de tempo intrínseco e que acontece somente uma vez em toda a execução do software, ele pode ser desconsiderado do benchmark.
 
Fica a dica para quem for medir o tempo de execução de seu algoritmo,
 
Abraços,
 
Daniel Medina
MSc. Student - Mechanical Engineering
State University of Campinas


 
2008/12/20 Labaki <lab...@fem.unicamp.br>
Reply all
Reply to author
Forward
0 new messages