Ghetto benchmark test
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 21 Nov 2012 02:50:02 +0000 (18:50 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 21 Nov 2012 02:50:02 +0000 (18:50 -0800)
Juan had a problem with code similar to this.  If you don't do
res += whatever
and juse do
res = whatever
(his example code), then you could get varying results based on what
else you put in the loop.  Specifically, if you do some extra stuff like
a read_tsc() and track the number of loop iterations, then the critical
path of the inner loop is actually shorter than without, leading to a
10-20% performance difference.

kern/src/schedule.c
tests/juan_test.c [new file with mode: 0644]
user/parlib/include/i686/arch.h
user/parlib/include/riscv/arch.h
user/parlib/include/sparc/arch.h

index d9ab4e2..94049f7 100644 (file)
@@ -872,3 +872,22 @@ void print_proc_prov(struct proc *p)
                       spc_i->alloc_proc ? spc_i->alloc_proc->pid : 0,
                       spc_i->alloc_proc);
 }
+
+void next_core(uint32_t pcoreid)
+{
+       struct sched_pcore *spc_i;
+       bool match = FALSE;
+       spin_lock(&sched_lock);
+       TAILQ_FOREACH(spc_i, &idlecores, alloc_next) {
+               if (spc2pcoreid(spc_i) == pcoreid) {
+                       match = TRUE;
+                       break;
+               }
+       }
+       if (match) {
+               TAILQ_REMOVE(&idlecores, spc_i, alloc_next);
+               TAILQ_INSERT_HEAD(&idlecores, spc_i, alloc_next);
+               printk("Pcore %d will be given out next (from the idles)\n", pcoreid);
+       }
+       spin_unlock(&sched_lock);
+}
diff --git a/tests/juan_test.c b/tests/juan_test.c
new file mode 100644 (file)
index 0000000..d58ff9e
--- /dev/null
@@ -0,0 +1,66 @@
+#include <stdio.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* OS dependent #incs */
+#include <parlib.h>
+#include <vcore.h>
+#include <timing.h>
+
+static uint32_t __get_pcoreid(void)
+{
+       return __procinfo.vcoremap[vcore_id()].pcoreid;
+}
+
+static __attribute__ ((noinline)) int juan_work(void)
+{
+    const int MAX_ITER = 100000;
+    register int res = 0;
+    for (int i = 0; i < MAX_ITER; ++i) {
+        for (int j = 0; j < i; ++j) {
+            res += (i * 2 - 5 * j) / 3;
+        }
+    }
+       return res;
+}
+
+static void juan_test(void)
+{
+       unsigned long long usec_diff;
+       struct timeval start_tv = {0};
+       struct timeval end_tv = {0};
+       int res;
+
+       printf("We are %sin MCP mode, running on vcore %d, pcore %d\n",
+              (in_multi_mode() ? "" : "not "), vcore_id(),
+              __get_pcoreid());
+
+       if (gettimeofday(&start_tv, 0))
+               perror("Start time error...");
+
+       res = juan_work();
+
+       if (gettimeofday(&end_tv, 0))
+               perror("End time error...");
+
+       usec_diff = (end_tv.tv_sec - start_tv.tv_sec) * 1000000 +
+                   (end_tv.tv_usec - start_tv.tv_usec);
+
+    printf("Result: %d Usec diff: %llu\n", res, usec_diff);
+}
+
+void *juan_thread(void* arg)
+{      
+       juan_test();
+}
+
+int main(int argc, char** argv) 
+{
+       pthread_t child;
+       void *child_ret;
+       juan_test();
+       printf("Spawning thread, etc...\n");
+       pthread_create(&child, NULL, &juan_thread, NULL);
+       pthread_join(child, &child_ret);
+} 
index ee7ad75..e8d1c53 100644 (file)
@@ -34,6 +34,34 @@ read_tsc(void)
 }
 
 static __inline void
+cpuid(uint32_t info1, uint32_t info2, uint32_t *eaxp, uint32_t *ebxp,
+      uint32_t *ecxp, uint32_t *edxp)
+{
+       uint32_t eax, ebx, ecx, edx;
+       /* Can select with both eax (info1) and ecx (info2) */
+       asm volatile("cpuid" 
+               : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+               : "a" (info1), "c" (info2));
+       if (eaxp)
+               *eaxp = eax;
+       if (ebxp)
+               *ebxp = ebx;
+       if (ecxp)
+               *ecxp = ecx;
+       if (edxp)
+               *edxp = edx;
+}
+
+static __inline uint64_t
+read_tsc_serialized(void)
+{
+       uint64_t tsc;
+       cpuid(0x0, 0x0, 0, 0, 0, 0);
+       tsc = read_tsc();
+       return tsc;
+}
+
+static __inline void
 cpu_relax(void)
 {
        asm volatile("pause" : : : "memory");
index aef6bb1..d34dcb0 100644 (file)
@@ -27,6 +27,12 @@ read_tsc(void)
        return (uint64_t)cycles;
 }
 
+static __inline uint64_t
+read_tsc_serialized(void)
+{
+       return read_tsc();
+}
+
 static __inline void
 cpu_relax(void)
 {
index 0142ded..ad0f471 100644 (file)
@@ -43,6 +43,12 @@ read_tsc(void)
        return read_perfctr(0,0);
 }
 
+static __inline uint64_t
+read_tsc_serialized(void)
+{
+       return read_tsc();
+}
+
 static __inline void
 cpu_relax(void)
 {