2 * Copyright (C) 2010 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #define N_PAGES (4096)
26 #define WARMUP (1<<10)
28 #define WORKLOAD (1<<24)
30 int numPagesList[] = {
31 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
32 12, 14, 16, 18, 20, 24, 28, 30, 32, 34, 48, 62, 64, 66, 80,
33 96, 112, 128, 144, 160, 320, 480, 496, 512, 528, 544, 576, 640, 960,
34 1024, 2048, 3072, 4000,
37 static unsigned long long stop_watch()
40 t.tv_sec = t.tv_nsec = 0;
41 clock_gettime(CLOCK_MONOTONIC, &t);
42 return t.tv_sec*1000000000ULL + t.tv_nsec;
47 char *mem = malloc((N_PAGES+1) * 4096);
52 /* Align to page start */
53 mem = (char *) ((intptr_t) (mem + 4096) & ~0xfff);
55 for (j = 0; j < sizeof(numPagesList)/sizeof(int); j++) {
56 int numPages = numPagesList[j];
61 * page 0 page 1 page 2 .... page N
62 * ------ ------ ------ ------
63 * word 0 -> word 0 -> word 0 -> .... -> word 0 -> (page 0/word 0)
65 * word 1023 word 1023 word 1023 : word 1023
67 for (i = 0; i < numPages; i++) {
68 int nextPageIdx = (pageIdx + 1) % numPages;
69 /* Looks like spread the pointer across cache lines introduce noise
70 * to get to the asymptote
71 * int nextEntryOffset = (entryOffset + 32) % 1024;
73 int nextEntryOffset = entryOffset;
75 if (i != numPages -1) {
76 *(intptr_t *) (mem + 4096 * pageIdx + entryOffset) =
77 (intptr_t) (mem + 4096 * nextPageIdx + nextEntryOffset);
79 /* Last page - form the cycle */
80 *(intptr_t *) (mem + 4096 * pageIdx + entryOffset) =
84 pageIdx = nextPageIdx;
85 entryOffset = nextEntryOffset;
88 /* Starting point of the pointer chase */
89 p = (intptr_t *) &mem[0];
91 /* Warmup (ie pre-thrash the memory system */
92 for (i = 0; i < WARMUP; i++) {
97 unsigned long long t0 = stop_watch();
98 for (i = 0; i < WORKLOAD; i++) {
101 unsigned long long t1 = stop_watch();
103 /* To keep p from being optimized by gcc */
105 printf("%d, %f\n", numPages, (float) (t1 - t0) / WORKLOAD);