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