]> git.saurik.com Git - apple/xnu.git/blame - tools/tests/superpages/measure_tlbs.c
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / tools / tests / superpages / measure_tlbs.c
CommitLineData
b0d623f7
A
1#include <stdio.h>
2#include <stdlib.h>
3#include <signal.h>
4#include <setjmp.h>
5#include <mach/mach.h>
6#include <mach/mach_vm.h>
7#include <time.h>
8
9#define SUPERPAGE_SIZE (2*1024*1024)
10#define SUPERPAGE_MASK (-SUPERPAGE_SIZE)
11#define SUPERPAGE_ROUND_UP(a) ((a + SUPERPAGE_SIZE-1) & SUPERPAGE_MASK)
12
13#define RUNS0 100000
14#define STEP 4 /* KB */
15#define START STEP
16#define MAX (1024*1024) /* KB */
17
18#define RUNS1 RUNS0
19#define RUNS2 (RUNS0/20)
20
21clock_t
0a7de745
A
22testt(boolean_t superpages, int mode, int write, int kb)
23{
b0d623f7
A
24 static int sum;
25 char *data;
26 unsigned int run, p, p2, i, res;
27 mach_vm_address_t addr = 0;
0a7de745
A
28 int pages = kb / 4;
29 mach_vm_size_t size = SUPERPAGE_ROUND_UP(pages * PAGE_SIZE); /* allocate full superpages */
b0d623f7
A
30 int kr;
31
32 kr = mach_vm_allocate(mach_task_self(), &addr, size, VM_FLAGS_ANYWHERE | (superpages? VM_FLAGS_SUPERPAGE_SIZE_2MB : VM_FLAGS_SUPERPAGE_NONE));
33
0a7de745 34 if (!addr) {
b0d623f7 35 return 0;
0a7de745 36 }
b0d623f7
A
37
38 data = (char*)(long)addr;
39
40 /* touch every base page to make sure everything is mapped and zero-filled */
0a7de745
A
41 for (p = 0; p < pages; p++) {
42 sum += data[p * PAGE_SIZE];
b0d623f7
A
43 }
44
45 clock_t a = clock(); /* start timing */
46 switch (mode) {
0a7de745
A
47 case 0: /* one byte every 4096 */
48 if (write) {
49 for (run = 0; run < RUNS0; run++) {
50 for (p = 0; p < pages; p++) {
51 data[p * PAGE_SIZE] = run & 0xFF;
b0d623f7 52 }
0a7de745
A
53 }
54 } else {
55 for (run = 0; run < RUNS0; run++) {
56 for (p = 0; p < pages; p++) {
57 sum += data[p * PAGE_SIZE];
b0d623f7
A
58 }
59 }
0a7de745
A
60 }
61 break;
62 case 1: /* every byte */
63 if (write) {
64 for (run = 0; run < RUNS1 / PAGE_SIZE; run++) {
65 for (i = 0; i < pages * PAGE_SIZE; i++) {
66 data[i] = run & 0xFF;
b0d623f7 67 }
0a7de745
A
68 }
69 } else {
70 for (run = 0; run < RUNS1 / PAGE_SIZE; run++) {
71 for (i = 0; i < pages * PAGE_SIZE; i++) {
72 sum += data[i];
b0d623f7
A
73 }
74 }
0a7de745
A
75 }
76 break;
77 case 2: /* random */
b0d623f7 78#define PRIME 15485863
0a7de745
A
79#define NODE_SIZE 128 /* bytes per node */
80#define NODE_ACCESSES 16 /* accesses per node */
81 p = 0;
82 if (write) {
83 for (run = 0; run < RUNS2 * pages; run++) {
84 p += PRIME;
85 p2 = p % (pages * PAGE_SIZE / NODE_SIZE);
b0d623f7 86//printf("p2 = %d\n", p2);
0a7de745
A
87 for (i = 0; i < NODE_ACCESSES; i++) {
88 data[p2 * NODE_SIZE + i] = run & 0xFF;
b0d623f7 89 }
0a7de745
A
90 }
91 } else {
92 for (run = 0; run < RUNS2 * pages; run++) {
93 p += PRIME;
94 p2 = p % (pages * PAGE_SIZE / NODE_SIZE);
95 for (i = 0; i < NODE_ACCESSES; i++) {
96 sum += data[p2 * NODE_SIZE + i];
b0d623f7
A
97 }
98 }
0a7de745
A
99 }
100 break;
b0d623f7
A
101 }
102 clock_t b = clock(); /* stop timing */
103 mach_vm_deallocate(mach_task_self(), addr, size);
0a7de745 104 res = b - a;
b0d623f7
A
105 res /= pages;
106 return res;
107}
108
0a7de745
A
109int
110main(int argc, char **argv)
111{
b0d623f7
A
112 int kb;
113 uint64_t time1, time2, time3, time4;
114
115 int mode;
116
117 printf("; m0 r s; m0 r b; m0 w s; m0 w b; m1 r s; m1 r b; m1 w s; m1 w b; m2 r s; m2 r b; m2 w s; m2 w b\n");
0a7de745 118 for (kb = START; kb < MAX; kb += STEP) {
b0d623f7 119 printf("%d", kb);
0a7de745
A
120 for (mode = 0; mode <= 2; mode++) {
121 time1 = time2 = time3 = time4 = -1;
122 time1 = testt(TRUE, mode, 0, kb); // read super
123 time2 = testt(FALSE, mode, 0, kb); // read base
124 time3 = testt(TRUE, mode, 1, kb); // write super
125 time4 = testt(FALSE, mode, 1, kb); // write base
b0d623f7
A
126 printf("; %lld; %lld; %lld; %lld", time1, time2, time3, time4);
127 fflush(stdout);
128 }
129 printf("\n");
130 }
131
132 return 0;
133}