diff options
author | Yogesh Tillu <yogesh.tillu@linaro.org> | 2015-04-14 11:36:55 +0530 |
---|---|---|
committer | Yogesh Tillu <yogesh.tillu@linaro.org> | 2015-04-15 08:01:49 +0530 |
commit | 5bfdec46898d6e9ce6cd9371fcf676ce1856c14e (patch) | |
tree | 5016a2b77e261eca5d992a1c47b7b0b65e9df5ae | |
parent | 5be680ecefdbd840289134719e532bfba2f57466 (diff) |
perf_ev_open:
Added support for all perf hw counter
Added getopt support for argument
Added print_usage for help
Reviewed-by: Anders Roxell <anders.roxell@linaro.org>
Signed-off-by: Yogesh Tillu <yogesh.tillu@linaro.org>
-rw-r--r-- | perf_ev_open.c | 92 |
1 files changed, 70 insertions, 22 deletions
diff --git a/perf_ev_open.c b/perf_ev_open.c index 3550bfd..9b06586 100644 --- a/perf_ev_open.c +++ b/perf_ev_open.c @@ -16,21 +16,27 @@ #include <sys/types.h> #include <sys/syscall.h> #include <linux/perf_event.h> +#include <getopt.h> static int fddev = -1; -__attribute__((constructor)) static void -init(void) + +static int counter_init(unsigned int counter) { static struct perf_event_attr attr; attr.type = PERF_TYPE_HARDWARE; - attr.config = PERF_COUNT_HW_CPU_CYCLES; + if (counter < 0 || counter > PERF_COUNT_HW_MAX) + return -1; + + attr.config = counter; fddev = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0); -} + if (fddev == -1) { + fprintf(stderr, + "Error opening perf_event_open for counter %llx\n" + , attr.config); + return -1; + } -__attribute__((destructor)) static void -fini(void) -{ - close(fddev); + return 0; } static inline long long cpucycles(void) @@ -38,10 +44,11 @@ static inline long long cpucycles(void) long long result = 0; if (read(fddev, &result, sizeof(result)) < sizeof(result)) return 0; + return result; } -/* Simple loop body to keep things interested. Make sure it gets inlined. */ +/* loop body to keep things interested. Make sure it gets inlined. */ static inline int loop(int* __restrict__ a, int* __restrict__ b, int n) { @@ -50,22 +57,56 @@ loop(int* __restrict__ a, int* __restrict__ b, int n) for (i = 0; i < n; ++i) if (a[i] > b[i]) sum += a[i] + 5; + return sum; } -int main(int ac, char **av) +void print_usage(char *argv) +{ + printf("Usage: %s -c perf_hw_counter -n length\n" + "%s - read perf hardware counters from userspace\n\n" + "-c\t perf_hw_counter is enum value of hw counter for platform\n" + "Refer to 'enum perf_hw_id'[file <linux/perf_event.h>] for hw\n" + "counter enum value in range of 0 to PERF_COUNT_HW_MAX\n" + "-n\t Length size array will implement busyloop\n" + "e.g.\n" + "\t%s -c 0 -n 64\n", argv, argv, argv); +} + +int main(int ac, char *argv[]) { long long time_start = 0; long long time_end = 0; - + int option = 0; + int len = -1, cnt = -1; int *a = NULL; int *b = NULL; - int len = 0; - int i, sum = 0; - if (ac != 2) - return -1; - len = atoi(av[1]); - printf("%s: len = %d\n", av[0], len); + int i, result, sum = 0; + + while ((option = getopt(ac, argv, "c:n:")) != -1) { + switch (option) { + case 'c': + cnt = atoi(optarg); + break; + case 'n': + len = atoi(optarg); + break; + default: + print_usage(argv[0]); + exit(EXIT_FAILURE); + } + } + + if (len == -1 || cnt == -1) { + print_usage(argv[0]); + exit(EXIT_FAILURE); + } + + if (counter_init(cnt) < 0) { + printf("Error: Counter Invalid\n"); + print_usage(argv[0]); + exit(EXIT_FAILURE); + } a = malloc(len*sizeof(*a)); b = malloc(len*sizeof(*b)); @@ -74,7 +115,7 @@ int main(int ac, char **av) a[i] = i+128; b[i] = i+64; } - printf("%s: beginning loop\n", av[0]); + time_start = time_end = 0; /* --------------------Critical section-------------- */ time_start = cpucycles(); @@ -82,20 +123,27 @@ int main(int ac, char **av) sum = loop(a, b, len); cpucycles(); } + time_end = cpucycles(); /* ---------------------------------- */ - printf("sum = %d; Avg time delta[Loop + Read] = %llu\n", sum, - (time_end - time_start)/1000); + result = (time_end-time_start)/1000; + printf("\nsum=%d Avg count [ Loop + Read ] = %ld\n", sum, + (time_end-time_start)/1000); time_start = time_end = 0; /* --------------------Critical section-------------- */ time_start = cpucycles(); for (i = 0; i < 1000; i++) sum = loop(a, b, len); + time_end = cpucycles(); /* ---------------------------------- */ - printf("sum = %d; Avg time delta[Loop]\t = %llu\n", sum, - (time_end - time_start)/1000); + printf("sum=%d Avg count [ Loop ] = %ld\n", sum, + (time_end-time_start)/1000); + printf("\n--------------------------------------------------------\n"); + printf("\tDelay[cpucycles]=%d", result-((time_end-time_start)/1000)); + printf("\n--------------------------------------------------------\n"); free(a); free(b); + close(fddev); return 0; } |