1/**
2 * \file
3 * \brief
4 */
5
6/*
7 * Copyright (c) 2007, 2008, 2009, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include "ump_bench.h"
16#include <string.h>
17#include <barrelfish/sys_debug.h>
18#include <arch/x86/barrelfish/perfmon.h>
19#include <arch/x86/barrelfish_kpi/perfmon_amd.h>
20#include <barrelfish/dispatcher_arch.h>
21
22#define MAX_COUNT 100
23static struct timestamps *timestamps;
24static struct timestamps *overhead;
25
26void experiment(coreid_t idx)
27{
28    timestamps = malloc(sizeof(struct timestamps) * MAX_COUNT);
29    assert(timestamps != NULL);
30    overhead = malloc(sizeof(struct timestamps) * MAX_COUNT);
31    assert(overhead != NULL);
32
33    dispatcher_handle_t my_dispatcher = curdispatcher();
34
35    struct bench_ump_binding *bu = (struct bench_ump_binding*)array[idx];
36    struct flounder_ump_state *fus = &bu->ump_state;
37    struct ump_chan *chan = &fus->chan;
38
39    struct ump_chan_state *send = &chan->send_chan;
40    struct ump_chan_state *recv = &chan->endpoint.chan;
41    volatile struct ump_message *msg;
42    struct ump_control ctrl;
43
44    printf("Running latency_cache between core %d and core %d\n",
45           my_core_id, idx);
46
47    for (int j = 0; j < 2; j++) { /* Pick event type */
48        uint64_t event;
49        if (j == 0) {
50            event = EVENT_AMD_DATA_CACHE_MISSES;
51        } else {
52            event = EVENT_AMD_INSTRUCTION_CACHE_MISSES;
53        }
54
55        /* Measure measurement overhead */
56        perfmon_setup(my_dispatcher, 0, event, 0, false);
57        for(size_t i = 0; i < MAX_COUNT; i++) {
58            overhead[i].time0 = rdpmc(0);
59            sys_debug_flush_cache();
60            overhead[i].time1 = rdpmc(0);
61        }
62        sys_debug_print_timeslice();
63        sys_debug_print_context_counter();
64
65        /* Run experiment */
66        perfmon_setup(my_dispatcher, 0, event, 0, false);
67        for (int i = 0; i < MAX_COUNT; i++) {
68            timestamps[i].time0 = rdpmc(0);
69            sys_debug_flush_cache();
70            while (!(msg = ump_impl_get_next(send, &ctrl)));
71            msg->header.control = ctrl;
72            while (!(msg = ump_impl_recv(recv)));
73            ump_impl_free_message(msg);
74            timestamps[i].time1 = rdpmc(0);
75        }
76        sys_debug_print_timeslice();
77        sys_debug_print_context_counter();
78
79        /* Print results */
80        char str[100];
81        if (event == EVENT_AMD_DATA_CACHE_MISSES) {
82            strcpy(str, "Data cache miss");
83        } else {
84            strcpy(str, "Instruction cache miss");
85        }
86        for (int i = MAX_COUNT / 10; i < MAX_COUNT; i++) {
87            printf("%s %d %"PRIuCYCLES" %"PRIuCYCLES"\n", str, i,
88                   overhead[i].time1 - overhead[i].time0,
89                   timestamps[i].time1 - timestamps[i].time0);
90        }
91    }
92}
93