diff options
Diffstat (limited to 'perf_event_open.c')
-rw-r--r-- | perf_event_open.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/perf_event_open.c b/perf_event_open.c new file mode 100644 index 0000000..fb44469 --- /dev/null +++ b/perf_event_open.c @@ -0,0 +1,99 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/syscall.h> +#include <linux/perf_event.h> + +static int fddev = -1; +__attribute__((constructor)) static void +init(void) +{ + static struct perf_event_attr attr; + attr.type = PERF_TYPE_HARDWARE; + attr.config = PERF_COUNT_HW_CPU_CYCLES; + fddev = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0); +} + +__attribute__((destructor)) static void +fini(void) +{ + close(fddev); +} + + 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. */ + static inline int +loop(int* __restrict__ a, int* __restrict__ b, int n) +{ + unsigned sum = 0; + int i = 0; + for (i = 0; i < n; ++i) + if (a[i] > b[i]) + sum += a[i] + 5; + return sum; +} + + int +main(int ac, char **av) +{ + long long time_start = 0; + long long time_end = 0; + + 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); + + a = malloc(len*sizeof(*a)); + b = malloc(len*sizeof(*b)); + + for (i = 0; i < len; ++i) { + 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(); + for (i = 0; i < 1000; i++) { + 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); + 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); + free(a); + free(b); + return 0; +} |