#include #include #include #include #include static inline void ccnt_start(void) { __asm__ volatile ("mcr p15, 0, %0, c9, c12, 1" :: "r"(1<<31)); } static inline void ccnt_stop(void) { __asm__ volatile ("mcr p15, 0, %0, c9, c12, 2" :: "r"(1<<31)); __asm__ volatile ("mcr p15, 0, %0, c9, c12, 0" :: "r"(0)); } static inline unsigned ccnt_read(void) { unsigned cc; __asm__ volatile ("mrc p15, 0, %0, c9, c13, 0" : "=r"(cc)); return cc; } static inline void ccnt_init(void) { ccnt_stop(); __asm__ volatile ("mcr p15, 0, %0, c9, c12, 0" :: "r"(5)); } static unsigned tv_diff(struct timeval *tv1, struct timeval *tv2) { return (tv2->tv_sec - tv1->tv_sec) * 1000000 + (tv2->tv_usec - tv1->tv_usec); } int main(int argc, char **argv) { struct timeval tv1, tv2; unsigned cc1, cc2, us; int spin; if (argc > 1) { if (!strcmp(argv[1], "1") || !strcmp(argv[1], "on")) { ccnt_init(); ccnt_start(); } else if (!strcmp(argv[1], "0") || !strcmp(argv[1], "off")) { ccnt_stop(); } else { fprintf(stderr, "usage: %s [on|off]\n", argv[0]); return 1; } return 0; } ccnt_init(); ccnt_start(); cc1 = ccnt_read(); gettimeofday(&tv1, NULL); spin = 1<<30; while (spin--) __asm__ volatile (""); cc2 = ccnt_read(); gettimeofday(&tv2, NULL); cc2 -= cc1; us = tv_diff(&tv1, &tv2); printf("%10u cycles in %7u us, %7.2f MHz\n", cc2, us, (float)cc2 / us); #if 0 cc1 = ccnt_read(); for (int i = 0; i < 100; i++) gettimeofday(&tv1, NULL); cc2 = ccnt_read(); printf("%u cycles in gettimeofday()\n", (cc2 - cc1) / 100); #endif ccnt_stop(); return 0; }