Merged the timing and measurement stuff together and cleaned it up a bit
[akaros.git] / inc / measure.h
1 #ifndef ROS_INC_MEASURE_H
2 #define ROS_INC_MEASURE_H
3
4 #include <inc/types.h>
5 #include <inc/stdio.h>
6 #include <inc/timer.h>
7 #include <inc/x86.h>
8
9 /* Macro for printing out debug information about our measurement setup.
10  * If MEASURE_DEBUG is set to 1, debug info will be printed.  If set to 0
11  * no debug info will be printed.
12  */
13 #define MEASURE_DEBUG   1
14 #if MEASURE_DEBUG
15 #ifndef ROS_KERNEL
16         #define mdebug(string, ...)     cprintf(string, ## __VA_ARGS__)
17 #else
18         #define mdebug(string, ...)     printk(string, ## __VA_ARGS__)
19 #endif
20 #else
21         #define mdebug(string, ...)
22 #endif
23
24 #define __measure_runtime(__CODE_BLOCK__)                                      \
25 ({                                                                             \
26         uint64_t time = start_timing();                                            \
27         __CODE_BLOCK__;                                                            \
28         stop_timing(time);                                                         \
29 })
30
31 #define measure_func_runtime(func, ...)                                        \
32 ({                                                                             \
33         __measure_runtime(func(__VA_ARGS__));                                      \
34 })
35
36
37 #define measure_function(func, iters, name)                                    \
38 ({                                                                             \
39         uint64_t ticks;                                                            \
40         cpuid(0, 0, 0, 0, 0);                                                      \
41         ticks = read_tsc();                                                        \
42         /* Run this a bunch of times to make sure its accurate */                  \
43         for(int i=0; i< (iters); i++) {                                            \
44                 func ;                                                                 \
45         }                                                                          \
46         cpuid(0, 0, 0, 0, 0);                                                      \
47         ticks = read_tsc() - ticks;                                                \
48         /* Compute the average and print it */                                     \
49         uint64_t a = (1000000000LL/(iters) * ticks) / (env->env_tscfreq);          \
50         if ((name))                                                                \
51                 cprintf("Measuring %s:\n"                                              \
52                         "    Total ticks:          %20lld\n"                           \
53                         "    Num Iterations:       %20d\n"                             \
54                         "    Time Per Iteration:   %20lld\n",                          \
55                 name, ticks, (iters), a);                                          \
56         ticks;                                                                     \
57 })
58
59 #define measure_function_async(func, _desc_type, _rsp_type, wait_func,         \
60                                    desc_name, i_iters, o_iters, name)              \
61 ({                                                                             \
62         uint64_t ticks;                                                            \
63         _desc_type* desc_array[i_iters];                                           \
64         _desc_type* desc_name;                                                     \
65         /* Could use an array of rsps, but we're throwing away the responses*/     \
66         _rsp_type rsp;                                                             \
67         error_t err;                                                               \
68         uint32_t safe_i_iters = i_iters;                                           \
69         cpuid(0, 0, 0, 0, 0);                                                      \
70         ticks = read_tsc();                                                        \
71         /* Run this a bunch of times to make sure its accurate */                  \
72         for(int i=0; i< (o_iters); i++) {                                          \
73                 for (int j = 0; j < (safe_i_iters); j++) {                             \
74                         err = func ;                                                       \
75                         if (err)                                                           \
76                                 (safe_i_iters) = j;                                            \
77                         desc_array[j] = desc_name;                                         \
78                 }                                                                      \
79                 for (int j = 0; j < (safe_i_iters); j++) {                             \
80                         wait_func(desc_array[j], &rsp);                                    \
81                 }                                                                      \
82         }                                                                          \
83         cpuid(0, 0, 0, 0, 0);                                                      \
84         ticks = read_tsc() - ticks;                                                \
85         /* Compute the average and print it */                                     \
86         uint64_t a = (1000000000LL/((o_iters)*(safe_i_iters)) * ticks) /           \
87                      (env->env_tscfreq);                                           \
88         if ((name))                                                                \
89                 cprintf("Measuring %s:\n"                                              \
90                         "    Total ticks:          %20lld\n"                           \
91                         "    Num Total Iterations: %20d\n"                             \
92                         "    Num Inner Iterations: %20d\n"                             \
93                         "    Time Per Iteration:   %20lld\n",                          \
94                 name, ticks, ((o_iters)*(safe_i_iters)), safe_i_iters, a);         \
95         ticks;                                                                     \
96 })
97
98 #define measure_async_call(func, desc_name, i_iters, o_iters, name)            \
99         measure_function_async(func, async_desc_t, async_rsp_t, waiton_async_call, \
100                                desc_name, i_iters, o_iters, name)
101
102 #endif /* !ROS_INC_MEASURE_H */
103
104
105