-//taken from [..see below..] and modifed a little.
-/*
- * lib_mem.c - library of routines used to analyze the memory hierarchy
- *
- * @(#)lib_mem.c 1.15 staelin@hpliclu2.hpli.hpl.hp.com
- *
- * Copyright (c) 2000 Carl Staelin.
- * Copyright (c) 1994 Larry McVoy.
- * Distributed under the FSF GPL with
- * additional restriction that results may published only if
- * (1) the benchmark is unmodified, and
- * (2) the version in the sccsid below is included in the report.
- * Support for this development by Sun Microsystems is gratefully acknowledged.
- */
+
+#define L4
#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
-// #include <l4/re/c/mem_alloc.h>
-// #include <l4/re/c/rm.h>
-// #include <l4/re/c/util/cap_alloc.h>
-// #include <l4/sys/err.h>
+#ifdef L4
#include <l4/util/rdtsc.h>
-#include <l4/sys/l4int.h>
#include <l4/sys/kip.h>
#include <l4/re/env.h>
+#include <l4/util/util.h>
-#define DEF_SIZE (4*1024)
-#define DEF_STRIDE (1)
-#define TEST_TYPE l4_uint8_t
-#define POLLITE_CACHE
-
-void use_dummy(int result);
-TEST_TYPE* words_initialize(l4_uint64_t max, int scale);
-l4_uint64_t parse_param( char param, int argc, char* argv[]);
-//-------------------------------------------------------------
-//---------L4 memory allocation--------------------------------
-/*------from examples/libs/l4re/c/ma+rm.c example-------------*/
-// static int allocate_mem(unsigned long size_in_bytes, unsigned long flags,
-// void **virt_addr)
-// {
-// int r;
-// l4re_ds_t ds;
-
-// /* Allocate a free capability index for our data space */
-// ds = l4re_util_cap_alloc();
-// if (l4_is_invalid_cap(ds))
-// return -L4_ENOMEM;
-
-// size_in_bytes = l4_trunc_page(size_in_bytes);
-
-// /* Allocate memory via a dataspace */
-// if ((r = l4re_ma_alloc(size_in_bytes, ds, flags)))
-// return r;
-
-// /* Make the dataspace visible in our address space */
-// *virt_addr = 0;
-// if ((r = l4re_rm_attach(virt_addr, size_in_bytes,
-// L4RE_RM_SEARCH_ADDR, ds, 0,
-// flags & L4RE_MA_SUPER_PAGES
-// ? L4_SUPERPAGESHIFT : L4_PAGESHIFT)))
-// return r;
-
-// /* Done, virtual address is in virt_addr */
-// return 0;
-// }
+#endif//L4
-// /**
-// * \brief Free previously allocated memory.
-// *
-// * \param virt_addr Virtual address return by allocate_mem
-// *
-// * \return 0 on success, error code otherwise
-// */
-// static int free_mem(void *virt_addr)
-// {
-// int r;
-// l4re_ds_t ds;
+#define WORKSET_SIZE (12*1024*1024)
+#define ALL_WORKSETS_BENCH
-// /* Detach memory from our address space */
-// if ((r = l4re_rm_detach_ds(virt_addr, &ds)))
-// return r;
+struct s {
+ int dummy[56];
+ struct s *ptr;
+};
-// /* Free memory at our memory allocator */
-// if ((r = l4re_ma_free(ds)))
-// return r;
+struct s array[0x1000000/sizeof(struct s)];
+#define REPEATS (0x20000000)
-// l4re_util_cap_free(ds);
-
-// /* All went ok */
-// return 0;
-// }
-
-//-------------------------------------------------------------
-static volatile l4_uint64_t use_result_dummy;
-void use_dummy(int result) { use_result_dummy += result; }
-
-/*
- * words_initialize
- *
- * This is supposed to create the order in which the words in a
- * "cache line" are used. Since we rarely know the cache line
- * size with any real reliability, we need to jump around so
- * as to maximize the number of potential cache misses, and to
- * minimize the possibility of re-using a cache line.
- */
-
-TEST_TYPE* words_initialize(l4_uint64_t max, int scale)
+static __inline__ uint64_t rdtsc(void)
{
- l4_uint64_t i, j, nbits;
- TEST_TYPE* words = (TEST_TYPE*) malloc(max);
- printf("%llu bytes allocated.\n", max*sizeof(TEST_TYPE));
- memset(words, 0, max);
-
- if (!words) return NULL;
+ uint32_t a, d;
+ //asm("cpuid");
+ asm volatile("rdtsc" : "=a" (a), "=d" (d));
- printf("Start init.");
- //bzero(words, max * sizeof(size_t));
-#ifdef POLLITE_CACHE
- for (i = max>>1, nbits = 0; i != 0; i >>= 1, nbits++);
- for (i = 0; i < max; ++i) {
- /* now reverse the bits */
- for (j = 0; j < nbits; j++) {
- if (i & (1<<j)) {
- words[i] |= (1<<(nbits-j-1));
- }
- }
- words[i] *= scale;
- }
- #endif
- return words;
+ return (((uint64_t)a) | (((uint64_t)d) << 32));
}
-l4_uint64_t parse_param( char param, int argc, char* argv[])
+int main(int argc, char *argv[])
{
- int i;
- for (i = 1; i < argc; i++){
- if ('-' == argv[i][0] && param == argv[i][1] ){
- return atoll(argv[i+1]);
- }
- }
- return 0;
-}
-
-
-int main(int argc, char* argv[])
-{
- printf("Benchmark started.\n");
- l4_uint64_t time_start, time_end, time_diff, j=0, i, stride = DEF_STRIDE;
- l4_uint64_t size = DEF_SIZE;
- // //size = parse_param('s', argc, argv);
- // //if ( !size )
- // //stride = parse_param('t', argc, argv);
- // //if ( !stride )
- TEST_TYPE * arry = words_initialize(size, 5);
- printf("Done init.\n");
- if (!arry) {
- printf("Init failed.");
- return -1;
- }
-
- printf("Start benchmark: array size is %llu, stride is %llu.\n", size, stride);
- l4_calibrate_tsc(l4re_kip());
-
+ unsigned int size;
while(1){
-
- time_start = l4_tsc_to_us(l4_rdtsc());
- for (i = 0; i < size; i += stride) {
- j += arry[i];
- }
- time_end = l4_tsc_to_us(l4_rdtsc());
- use_dummy(j);
-
- time_diff = (time_end-time_start);
- double baud = ((double) size*(sizeof(TEST_TYPE)))/ ((double) time_diff);
-
- printf("time: %llu us, baud: %lf bytes/us\n", time_diff, baud);
- sleep(1);
+#ifdef ALL_WORKSETS_BENCH
+ for (size = 1024; size <= sizeof(array); size *= 2)
+#else //!ALL_WORKSETS_BENCH
+ size = WORKSET_SIZE;
+ while (1)
+#endif
+ {
+ unsigned int i;
+ for (i=0; i < size / sizeof(array[0]); i++)
+ array[i].ptr = &array[i+1];
+ array[ size / sizeof(array[0]) - 1].ptr = &array[0];
+
+ i = REPEATS;
+ volatile struct s *p = &array[0];
+ uint64_t tic, tac;
+ tic = rdtsc();
+ while (i--) {
+ p = p->ptr;
+ //printf("%p\n", p);
+ }
+ tac = rdtsc();
+ printf("%d %llu\n", size, (tac - tic) / REPEATS);
+ fflush(stdout);
+ }
+ printf("10 sec wait and do again.\n");
+ l4_sleep(10000);
}
+ return 0;
}