Measurement infrastructure
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 6 May 2009 18:16:49 +0000 (11:16 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 6 May 2009 23:12:42 +0000 (16:12 -0700)
TSC frequency is stored in the env_t for now.

inc/env.h
inc/measure.h [new file with mode: 0644]
kern/env.c
kern/init.c
user/null.c

index bdb6909..f72c328 100644 (file)
--- a/inc/env.h
+++ b/inc/env.h
@@ -54,8 +54,10 @@ struct Env {
        pde_t *env_pgdir;                       // Kernel virtual address of page dir
        physaddr_t env_cr3;                     // Physical address of page dir
        // TODO - give these two proper types (pointers to structs)
-       void* env_procinfo;     // KVA of per-process shared info table (RO)
-       void* env_procdata;     // KVA of per-process shared data table (RW)
+       void* env_procinfo;             // KVA of per-process shared info table (RO)
+       void* env_procdata;             // KVA of per-process shared data table (RW)
+       // Eventually want to move this to a per-system shared-info page
+       uint64_t env_tscfreq;           // Frequency of the TSC for measurements
 };
 
 #endif // !ROS_INC_ENV_H
diff --git a/inc/measure.h b/inc/measure.h
new file mode 100644 (file)
index 0000000..ba387a2
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef ROS_INC_MEASURE_H
+#define ROS_INC_MEASURE_H
+
+#include <inc/types.h>
+#include <inc/stdio.h>
+#include <inc/x86.h>
+
+#define measure_function(func, iters, name)                                    \
+({                                                                             \
+       uint64_t ticks;                                                            \
+       cpuid(0, 0, 0, 0, 0);                                                      \
+       ticks = read_tsc();                                                        \
+       /* Run this a bunch of times to make sure its accurate */                  \
+       for(int i=0; i< (iters); i++) {                                            \
+               func ;                                                                 \
+       }                                                                          \
+       cpuid(0, 0, 0, 0, 0);                                                      \
+       ticks = read_tsc() - ticks;                                                \
+       /* Compute the average and print it */                                     \
+       uint64_t a = (1000000000LL/(iters) * ticks) / (env->env_tscfreq);          \
+       if ((name))                                                                \
+               cprintf("Measuring %s:\n"                                              \
+                       "    Total ticks:        %20lld\n"                             \
+                       "    Num Iterations:     %20d\n"                               \
+                       "    Time Per Iteration: %20lld\n",                            \
+               name, ticks, (iters), a);                                          \
+       ticks;                                                                     \
+})
+
+#endif /* !ROS_INC_MEASURE_H */
index df4ae80..01e2d3d 100644 (file)
@@ -235,6 +235,7 @@ env_alloc(env_t **newenv_store, envid_t parent_id)
        LIST_REMOVE(e, env_link);
        *newenv_store = e;
 
+       e->env_tscfreq = tsc_freq;
        // TODO: for now, the only info at procinfo is this env's struct
        // note that we need to copy this over every time we make a change to env
        // that we want userspace to see.  also note that we don't even want to
index 7d699f6..1da0ebe 100644 (file)
@@ -80,8 +80,9 @@ void kernel_init(multiboot_info_t *mboot_info)
        //ENV_CREATE(user_badsegment);
        //ENV_CREATE(user_divzero);
        //ENV_CREATE(user_buggyhello);
-       ENV_CREATE(user_hello);
-       ENV_CREATE(user_hello);
+       //ENV_CREATE(user_hello);
+       //ENV_CREATE(user_hello);
+       ENV_CREATE(user_null);
        //ENV_CREATE(user_evilhello);
 
        // We only have one user environment for now, so just run it.
@@ -89,17 +90,18 @@ void kernel_init(multiboot_info_t *mboot_info)
        // run_env_handler just runs the first env, like the prev command
        // need a way to have call_func to pass a pointer to a struct for arguments
        smp_call_function_single(2, run_env_handler, &envs[0], 0);
-       smp_call_function_single(4, run_env_handler, &envs[1], 0);
+       //smp_call_function_single(4, run_env_handler, &envs[1], 0);
 
        // wait 5 sec, then print what's in shared mem
        udelay(5000000);
-
+       /*
        printk("Attempting to run two syscalls at the beginning of procdata for env 0 and 1:\n\n");
        while (1) {
                process_generic_syscalls(&envs[0], 1);
-               process_generic_syscalls(&envs[1], 1);
+               //process_generic_syscalls(&envs[1], 1);
                cpu_relax();
        }
+       */
        panic("Don't Panic");
 }
 
index 6b09fad..2e370a1 100644 (file)
@@ -3,32 +3,27 @@
 #include <inc/types.h>
 #include <inc/syscall.h>
 #include <inc/x86.h>
+#include <inc/measure.h>
 
-uint64_t avg(uint32_t (COUNT(length) array)[], int length) 
+#define NUM_ITERATIONS 100000
+uint64_t times[NUM_ITERATIONS];
+
+uint64_t total(uint64_t (COUNT(length) array)[], int length) 
 {
        uint64_t sum = 0;
        for(int i=0; i<length; i++) {
                sum+=array[i];
        }
-       return (length > 0) ? sum/((uint64_t)length) : 0;
+       return sum;
+       //return (length > 0) ? sum/((uint64_t)length) : 0;
 }
 
 void umain(void)
 {
-       //Get the measurements a bunch of times to make sure its accurate
-       #define NUM_ITERATIONS  500
-       uint32_t times[NUM_ITERATIONS];
-       for(int i=0; i<NUM_ITERATIONS; i++) {
-               //times[i] = get_time();
-               sys_null();
-               //times[i] = get_time() - times[i];
-       }
-       
-       //Compute the average and print it
-       uint64_t a = avg(times, NUM_ITERATIONS);
-       cprintf_async("Average latency: %ld", a);
-       //cprintf("Standard Deviation: %d", stddev);
+       measure_function(sys_null(), NUM_ITERATIONS, "sys_null");
+       measure_function(asm volatile("nop;"), NUM_ITERATIONS, "nop");
+       measure_function(cprintf("hello\n"), 2, "printf");
 
-       //Spin to make sure we don't have any resources dealocated before done
+       // Spin to make sure we don't have any resources deallocated before done
        while(1);
 }