#include #include /* * Rotinas para usar o cycle counter */ /* Initializar as variaveis do cycle counter */ static unsigned cyc_hi = 0; static unsigned cyc_lo = 0; /* Colocar em *hi e *lo os bits mais e menos significativos do cycle counter. * Requer codigo assembly para usar a instrucao "rdtsc". */ void access_counter(unsigned *hi, unsigned *lo) { asm("rdtsc; movl %%edx,%0; movl %%eax,%1" /* Ler o cycle counter */ : "=r" (*hi), "=r" (*lo) /* e mover resultados para */ : /* No input */ /* os dois outputs */ : "%edx", "%eax"); } /* Registar o valor actual do cycle counter. */ void start_counter() { access_counter(&cyc_hi, &cyc_lo); } /* Devolver o numero de ciclos desde a ultima chamada a start_counter. */ double get_counter() { unsigned ncyc_hi, ncyc_lo; unsigned hi, lo, borrow; double result; /* Obter o valor do cycle counter */ access_counter(&ncyc_hi, &ncyc_lo); /* Efectuar subtraccao de precisao dupla */ lo = ncyc_lo - cyc_lo; borrow = lo > ncyc_lo; hi = ncyc_hi - cyc_hi - borrow; result = (double) hi * (1 << 30) * 4 + lo; if (result < 0) { fprintf(stderr, "Erro: contador devolve valor negativo: %.0f\n", result); } return result; } /* $begin mhz */ /* Estimar a frequencia do clock medindo o numero de ciclos decorridos */ /* enquanto o processador e' colocado a "dormir" */ double mhz(int verbose, int sleeptime) { double rate; start_counter(); sleep(sleeptime); rate = get_counter() / (1e6*sleeptime); if (verbose) printf("Frequencia de clock do processador ~= %.1f MHz\n", rate); return rate; } /* Programa para estimar a frequencia do clock do processador */ void main() { mhz(1,1); // verbose, 1 seg }