/* Random/sequential read/write benchmark. */ /* Copyright 2005-2006 Gopalan Sivathanu */ /* Copyright 2005-2006 Charles P. Wright */ /* Copyright 2005-2006 The Research Foundation of SUNY */ /* We need large file support so we have 2x memory, but we need to test the * monitor's large file support first. */ #define _GNU_SOURCE #define __USE_LARGEFILE64 #define _FILE_OFFSET_BITS 64 #ifndef O_DIRECT #define O_DIRECT 040000 #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define APP "micro" #define READ 1 #define WRITE 2 #define SEQ 3 #define RAND 4 #define PROFILE_SYSCALLS #ifdef PROFILE_SYSCALLS #define OP_FORK 0 #define OP_LLSEEK 1 #define OP_PREAD 2 #define OP_PWRITE 3 #define OP_OPEN 4 #define OP_CLOSE 5 #define OP_MAX 6 #define BUCKETS 32 char* op_names[] = {"OP_FORK", "OP_LSEEK", "OP_PREAD", "OP_PWRITE", "OP_OPEN", "OP_CLOSE"}; int* aggregate_stats; unsigned long long* aggregate_count; int shmid; #define RDTSC(qp) \ do { \ unsigned long lowPart, highPart; \ __asm__ __volatile__("rdtsc" : "=a" (lowPart), "=d" (highPart)); \ qp = (((unsigned long long) highPart) << 32) | lowPart; \ } while (0); #define AGGREGATE_PRE \ long long lAggregate; \ RDTSC(lAggregate); #define AGGREGATE_POST(op) \ long long ll; \ int bucket, delay; \ RDTSC(ll); \ delay = (int)(ll - lAggregate); \ aggregate_count[(op * 2)]++; \ aggregate_count[(op * 2) + 1] += delay; \ delay = (int)(delay >> 5); \ bucket = 0; \ while (delay >>= 1) \ bucket++; \ aggregate_stats[op * BUCKETS + bucket]++; #define AGGREGATE_STATS(what, op) \ do { \ AGGREGATE_PRE; \ what; \ AGGREGATE_POST((op)); \ } while (0); #define AGGREGATE_STATS_PRINT \ { \ int i, ii; \ for (i = 0; i < OP_MAX; i++) { \ printf("%s %llu %llu ", op_names[i], aggregate_count[(i * 2)], aggregate_count[(i * 2) + 1]); \ for (ii = 0; ii < BUCKETS; ii++) \ printf("%d ", aggregate_stats[(i * BUCKETS) + ii]); \ printf ("\n"); \ } \ } #define AGGREGATE_STATS_EXIT shmdt(aggregate_stats); #define AGGREGATE_STATS_INIT \ aggregate_stats = mmap(NULL, BUCKETS * sizeof(int) * OP_MAX, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, 0, 0); \ aggregate_count = mmap(NULL, 2 * sizeof(unsigned long long) * OP_MAX, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, 0, 0); \ if (!aggregate_stats || !aggregate_count) { \ perror("mmap"); \ } \ memset(aggregate_stats, 0, BUCKETS * sizeof(int) * OP_MAX); \ memset(aggregate_stats, 0, 2 * sizeof(unsigned long long) * OP_MAX); #else #define AGGREGATE_STATS_INIT #define AGGREGATE_STATS_PRINT #define AGGREGATE_STATS_EXIT #define AGGREGATE_STATS(what, op) what; #endif // PROFILE_SYSCALLS int op, pattern, numops, numpro,ssize, debug, timelimit, warmlimit, openflags; unsigned int seed; char fname[256]; unsigned int *order; int elements; int *didops; int *warmops; void usage(void) { printf("Usage: micro [--read|--write] [--random|--seq] [-s ] [-n ] [-p ] [-t