diff options
Diffstat (limited to 'powerpc/pmu/count_instructions.c')
-rw-r--r-- | powerpc/pmu/count_instructions.c | 147 |
1 files changed, 0 insertions, 147 deletions
diff --git a/powerpc/pmu/count_instructions.c b/powerpc/pmu/count_instructions.c deleted file mode 100644 index 4622117..0000000 --- a/powerpc/pmu/count_instructions.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2013, Michael Ellerman, IBM Corp. - * Licensed under GPLv2. - */ - -#define _GNU_SOURCE - -#include <stdio.h> -#include <stdbool.h> -#include <string.h> -#include <sys/prctl.h> - -#include "event.h" -#include "utils.h" -#include "lib.h" - -extern void thirty_two_instruction_loop(u64 loops); - -static void setup_event(struct event *e, u64 config, char *name) -{ - event_init_opts(e, config, PERF_TYPE_HARDWARE, name); - - e->attr.disabled = 1; - e->attr.exclude_kernel = 1; - e->attr.exclude_hv = 1; - e->attr.exclude_idle = 1; -} - -static int do_count_loop(struct event *events, u64 instructions, - u64 overhead, bool report) -{ - s64 difference, expected; - double percentage; - - prctl(PR_TASK_PERF_EVENTS_ENABLE); - - /* Run for 1M instructions */ - thirty_two_instruction_loop(instructions >> 5); - - prctl(PR_TASK_PERF_EVENTS_DISABLE); - - event_read(&events[0]); - event_read(&events[1]); - - expected = instructions + overhead; - difference = events[0].result.value - expected; - percentage = (double)difference / events[0].result.value * 100; - - if (report) { - event_report(&events[0]); - event_report(&events[1]); - - printf("Looped for %llu instructions, overhead %llu\n", instructions, overhead); - printf("Expected %llu\n", expected); - printf("Actual %llu\n", events[0].result.value); - printf("Delta %lld, %f%%\n", difference, percentage); - } - - event_reset(&events[0]); - event_reset(&events[1]); - - if (difference < 0) - difference = -difference; - - /* Tolerate a difference below 0.0001 % */ - difference *= 10000 * 100; - if (difference / events[0].result.value) - return -1; - - return 0; -} - -/* Count how many instructions it takes to do a null loop */ -static u64 determine_overhead(struct event *events) -{ - u64 current, overhead; - int i; - - do_count_loop(events, 0, 0, false); - overhead = events[0].result.value; - - for (i = 0; i < 100; i++) { - do_count_loop(events, 0, 0, false); - current = events[0].result.value; - if (current < overhead) { - printf("Replacing overhead %llu with %llu\n", overhead, current); - overhead = current; - } - } - - return overhead; -} - -static int test_body(void) -{ - struct event events[2]; - u64 overhead; - - setup_event(&events[0], PERF_COUNT_HW_INSTRUCTIONS, "instructions"); - setup_event(&events[1], PERF_COUNT_HW_CPU_CYCLES, "cycles"); - - if (event_open(&events[0])) { - perror("perf_event_open"); - return -1; - } - - if (event_open_with_group(&events[1], events[0].fd)) { - perror("perf_event_open"); - return -1; - } - - overhead = determine_overhead(events); - printf("Overhead of null loop: %llu instructions\n", overhead); - - /* Run for 1Mi instructions */ - FAIL_IF(do_count_loop(events, 1000000, overhead, true)); - - /* Run for 10Mi instructions */ - FAIL_IF(do_count_loop(events, 10000000, overhead, true)); - - /* Run for 100Mi instructions */ - FAIL_IF(do_count_loop(events, 100000000, overhead, true)); - - /* Run for 1Bi instructions */ - FAIL_IF(do_count_loop(events, 1000000000, overhead, true)); - - /* Run for 16Bi instructions */ - FAIL_IF(do_count_loop(events, 16000000000, overhead, true)); - - /* Run for 64Bi instructions */ - FAIL_IF(do_count_loop(events, 64000000000, overhead, true)); - - event_close(&events[0]); - event_close(&events[1]); - - return 0; -} - -static int count_instructions(void) -{ - return eat_cpu(test_body); -} - -int main(void) -{ - return test_harness(count_instructions, "count_instructions"); -} |