1/**
2 * \file
3 * \brief library for benchmarking the network related code
4 *
5 */
6
7/*
8 * Copyright (c) 2007, 2008, 2009, 2010, 2011 ETH Zurich.
9 * All rights reserved.
10 *
11 * This file is distributed under the terms in the attached LICENSE file.
12 * If you do not find this file, copies can be found by writing to:
13 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
14 */
15
16#ifndef NETBENCH_C_
17#define NETBENCH_C_
18
19#include <netbench/netbench.h>
20#include <string.h>
21
22#define MACHINE_CLK_UNIT    (1000000)
23
24#define MACHINE_CLOCK_SPEED  (2800)
25#define IN_SECONDS(x)   (((x)/(MACHINE_CLOCK_SPEED))/(MACHINE_CLK_UNIT))
26
27#define CONVERT_TO_SEC
28
29//#ifdef CONVERT_TO_SEC
30
31
32// For recording statistics
33float in_seconds(uint64_t cycles)
34{
35    float ans;
36    ans = cycles / MACHINE_CLOCK_SPEED;
37    ans = ans / MACHINE_CLK_UNIT;
38    return ans;
39}
40
41#if 0
42uint64_t in_seconds(uint64_t cycles)
43{
44    return cycles;
45}
46#endif // CONVERT_TO_SEC
47
48uint64_t my_avg(uint64_t sum, uint64_t n)
49{
50    if (n == 0) {
51        return sum;
52    }
53    return (sum/n);
54}
55
56
57// reset the statistics
58void netbench_reset(struct netbench_details *nbp)
59{
60    memset(nbp->stats, 0, (nbp->total_events * nbp->event_elements *
61                sizeof(uint64_t)));
62    nbp->status = 0;
63}
64
65
66// Allocate the memory for storing netbench numbers
67struct netbench_details *netbench_alloc(char *name, uint32_t total_events)
68{
69    struct netbench_details *nbp = (struct netbench_details *)
70        malloc(sizeof(struct netbench_details));
71    if (nbp == NULL) {
72        printf("ERROR: malloc failed in alloc_netbench\n");
73        abort();
74    }
75
76    memset(nbp, 0, sizeof(struct netbench_details));
77    nbp->total_events = total_events;
78    nbp->event_elements = EVENT_ELEMENTS;
79
80    nbp->stats = malloc(total_events * (nbp->total_events *
81                nbp->event_elements * sizeof(uint64_t)));
82
83    if (nbp->stats == NULL) {
84        printf("ERROR: malloc failed in alloc_netbench\n");
85        abort();
86    }
87
88
89    netbench_reset(nbp);
90    strncpy(nbp->name, name, 63);
91    return nbp;
92}/* end function: netbench_alloc */
93
94
95void netbench_record_event(struct netbench_details *nbp,
96        uint32_t event_type, uint64_t value)
97{
98    if (nbp == NULL) {
99        return;
100    }
101
102    if (nbp->stats == NULL) {
103        return;
104    }
105
106    if (nbp->status == 0) {
107        return;
108    }
109    assert(event_type < nbp->total_events);
110
111    ++nbp->stats[(event_type * nbp->event_elements) + RDT_COUNT];
112    nbp->stats[(event_type * nbp->event_elements) + RDT_SUM] += value;
113
114    // if first element
115    if (nbp->stats[(event_type * nbp->event_elements) + RDT_COUNT] == 1) {
116        nbp->stats[(event_type * nbp->event_elements) + RDT_MAX] = value;
117        nbp->stats[(event_type * nbp->event_elements) + RDT_MIN] = value;
118        return;
119    }
120    if (value > nbp->stats[(event_type * nbp->event_elements) + RDT_MAX]) {
121        nbp->stats[(event_type * nbp->event_elements) + RDT_MAX] = value;
122    }
123    if (value < nbp->stats[(event_type * nbp->event_elements) + RDT_MIN]) {
124        nbp->stats[(event_type * nbp->event_elements) + RDT_MIN]= value;
125    }
126} // end function: netbench_record_event
127
128void netbench_record_event_no_ts(struct netbench_details *nbp,
129        uint8_t event_type)
130{
131    if (nbp == NULL) {
132        return;
133    }
134
135    if (nbp->stats == NULL) {
136        return;
137    }
138
139    if (nbp->status == 0) {
140        return;
141    }
142    assert(event_type < nbp->total_events);
143    ++nbp->stats[(event_type * nbp->event_elements) + RDT_COUNT];
144}
145
146// Takes time difference
147void netbench_record_event_simple(struct netbench_details *nbp,
148        uint8_t event_type, uint64_t ts)
149{
150    uint64_t delta = rdtsc() - ts;
151    netbench_record_event(nbp, event_type, delta);
152}
153
154
155void netbench_print_event_stat(struct netbench_details *nbp,
156        uint8_t event_type, char *event_name, int type)
157{
158    if (nbp == NULL) {
159        return;
160    }
161
162    if (nbp->stats == NULL) {
163        return;
164    }
165
166    if (nbp->status == 0) {
167        return;
168    }
169
170    assert(event_type < nbp->total_events);
171
172    if (type == 1) {
173        printf("Event %20s (%"PRIu8"): N[%"PRIu64"], AVG[%"PU"], "
174          "MAX[%"PU"], MIN[%"PU"], TOTAL[%"PU"]\n", event_name, event_type,
175          nbp->stats[(event_type * nbp->event_elements) + RDT_COUNT],
176          in_seconds(my_avg(nbp->stats[(event_type * nbp->event_elements)
177                    + RDT_SUM],
178          nbp->stats[(event_type * nbp->event_elements) + RDT_COUNT])),
179          in_seconds(nbp->stats[(event_type * nbp->event_elements) + RDT_MAX]),
180          in_seconds(nbp->stats[(event_type * nbp->event_elements) + RDT_MIN]),
181          in_seconds(nbp->stats[(event_type * nbp->event_elements) + RDT_SUM])
182          );
183    }
184    else {
185    printf("Event %20s (%"PRIu8"): N[%"PRIu64"], AVG[%"PRIu64"], "
186          "MAX[%"PRIu64"], MIN[%"PRIu64"], TOTAL[%"PRIu64"]\n", event_name,
187          event_type,
188          nbp->stats[(event_type * nbp->event_elements) + RDT_COUNT],
189          (my_avg(nbp->stats[(event_type * nbp->event_elements) + RDT_SUM],
190                 nbp->stats[(event_type * nbp->event_elements) + RDT_COUNT])),
191          (nbp->stats[(event_type * nbp->event_elements) + RDT_MAX]),
192          (nbp->stats[(event_type * nbp->event_elements) + RDT_MIN]),
193          (nbp->stats[(event_type * nbp->event_elements) + RDT_SUM]));
194    }
195} // end function: print_event_stat
196
197void netbench_print_all_stats(struct netbench_details *nbp)
198{
199    if (nbp == NULL) {
200        return;
201    }
202
203    if (nbp->stats == NULL) {
204        return;
205    }
206
207    if (nbp->status == 0) {
208        return;
209    }
210
211    for (int i = 0; i < nbp->total_events; ++i) {
212        netbench_print_event_stat(nbp, i, "S", 0);
213        netbench_print_event_stat(nbp, i, "C", 1);
214    } // end for: each event
215}
216
217#endif // NETBENCH_C_
218
219