• Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   13-02-2016

      Prezados membros do Clube do Hardware,

      Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:
        Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas ao formulário abaixo:    Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
Entre para seguir isso  
Seguidores 0
Tranzorb

Como criar delays de

8 posts neste tópico

Saudações pessoal,

Gostaria de saber se algum dos colegas conhece uma forma de criar delays de microssegundos em programas de linguagem C. O windows, em suas APIs, provê a função SLEEP, e várias linguagens possuem em suas bibliotecas funções semelhantes. Mas o menor intervalo de tempo possível de se executar com essas rotinas é 1 milissegundo (equivalente a 1000 microssegundos).

Imagino que, trazendo ao conhecimento do programa a duração do ciclo de instrução da máquina, ele pode calcular a quantidade de ciclos que são executados durante 1 microssegundo... Mas como descobrir a duração do ciclo de instrução? O programa precisa ser portátil. Logo, ele sempre terá que medir esse valor no início de sua execução, para adaptar-se às diferentes máquinas em que será instalado.

Alguém poderia ajudar?

Desde já, agradeço a todos,

Tranzorb.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom, você pode usar uma rotina com um loop, fazendo uma soma....a soma leva só um ciclo de clock pra ser feita. Então você faz a soma até q tenha passado um microsegundo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá sviola,

Essa, acredito, é a rotina mais usual para esse tipo de problema, e é uma das opções que estou cogitando e que até já tentei implementar.

O problema é que eu preciso conhecer a duração do ciclo de instrução da máquina para saber a quantidade de ciclos que meu loop deverá percorrer até que se passe 1 microssegundo.

Fora outros problemas que, acredito, precisarão ser contornados, como a distribução do tempo de processador, ou seja, penso que o tempo que o processador levará cuidando de outras tarefas manterá meu loop interrompido e terminará por somar tempo ao 1 microssegundo que desejo criar. Isso poderia ficar menos perceptível em delays maiores, mas, acredito que num de 1 microssegundo já é possível perceber deformações.

De qualquer forma, muito obrigado pela colaboração e aguardo mais idéias para a discussão.

Tranzorb.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olha, loop com somas não é um modo adequado de fazer isso.

Desde o Pentium os processadores tem um contador do número de ciclos que é a forma mais rápida de se medir o tempo. Só precisa fazer uma calibração, para transformar o número de ciclos em tempo (que é descobrir o clock do processador).

O contador é acessado pela instrução rdtsc (assembler, mas alguns compiladores já tem ela implementada para a linguagem). você não disse qual é o compilador que irá usar e também não entendi se irá rodar apeans no Windows ou também em outros SO (você diz que ele tem que ser portátil).

Se for apenas em Windows, ao invés de você criar toda a medição com base na instrução rdtsc, você pode usar uma versão da API do Windows que usa essa instrução, porém ela não te dá a mesma precisão, mas é suficiente para o que você precisa, pois na pior das hipóteses a precisão é de 1 microsegundo (na minha máquina é de 0.3 microsegundos, varia conforme o processador). Eu descobri um falha nessa função para processadores P4 com mais de 4GHz, mas isso não veremos tão cedo e acho que a MS corrige até lá.

Então, procure no google pela por QueryPerformanceCounter e QueryPerformanceFrequency. Para chamar a função se perde alguns microsegundos (+/-5ms), mas acho que serve para o que você quer. Qualquer coisa, procure pela instrução rdtsc, que a penalidade dela é de apenas 80-200 ciclos do processador (da ordem de décimos de microsegundo) e a resolução é de nanosegundos.

Sempre depende do clock do processador.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Estou agora sem compilador pra testar mas acredito que a solução abaixo funcione independentemente de SO(ANSI C).

Teste assim:

(inclua a biblioteca time.h)

void wait ( int microseconds )

{

clock_t endwait;

endwait = clock () + microseconds*CLK_TCK/(1000000);

while (clock() < endwait) {};

}

//CLK_TCK é uma constante que guarda o numero de TICKS por segundo. com a qual //você não precisa se preocupar pois ela é interna da biblioteca.

//Dividi por 10^6 para que converter para numero de ticks por milissegundos.

ps.: essa é uma pequena modificação do código encontrado em:

http://www.cplusplus.com/ref/

que é um site bem legal com que tem também a documentação das bibliotecas da STDLIB

Abraços!

Compartilhar este post


Link para o post
Compartilhar em outros sites

csilvano, esse dai não tem a precisão de microsegundos. Clock() tem resolução em torno de 10 ms.

Ai vai minha sugestão, para um com boa resolução:

Variáveis:


double start_time,clockrate;
static LARGE_INTEGER qw;

Funções:


void calibratetimer(void)
{
 QueryPerformanceFrequency(&qw);
 clockrate = (double)qw.QuadPart;
}
void starttimer(void)
{
QueryPerformanceCounter(&qw);
start_time = (1E6*(double)qw.QuadPart);
}

double readtimer(void)
{
 QueryPerformanceCounter(&qw);
 return ((1E6*(double)qw.QuadPart - start_time)/clockrate);  // tempo em microsegundos
}

Loop para aguardar o tempo que se quer aguardar:


calibratetimer();  // apenas a primeira vez, quando iniciar o processo
starttimer();
 while (readt()<tempoparaesperaremmicrosegundos)
 {   }

Compartilhar este post


Link para o post
Compartilhar em outros sites

Legal!

Tomara que funcione então.

Desculpem se me equivoquei com meu código... é que como eu tinha dito eu estou sem compilador para testar.

Abraços!

Compartilhar este post


Link para o post
Compartilhar em outros sites
Postado Originalmente por csilvano@01 jan 2005, 21:03

Legal!

Tomara que funcione então.

Desculpem se me equivoquei com meu código... é que como eu tinha dito eu estou sem compilador para testar.

Abraços!

Ah não tem o que se desculpar. E foi bom você falar no compilador. Esse código eu já usei no Mingw. Precisa adicionar o windows.h, também esqueci de citar.

Acredito que funcione bem no compilador da MS e Intel também, sem modificar nada.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!


Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.


Entrar agora
Entre para seguir isso  
Seguidores 0