xref: /aosp_15_r20/system/extras/tests/pftest/pftest.c (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2010 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  */
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker #include <stdio.h>
18*288bf522SAndroid Build Coastguard Worker #include <stdlib.h>
19*288bf522SAndroid Build Coastguard Worker #include <stdint.h>
20*288bf522SAndroid Build Coastguard Worker #include <unistd.h>
21*288bf522SAndroid Build Coastguard Worker #include <sys/time.h>
22*288bf522SAndroid Build Coastguard Worker #include <time.h>
23*288bf522SAndroid Build Coastguard Worker 
24*288bf522SAndroid Build Coastguard Worker #define N_PAGES (4096)
25*288bf522SAndroid Build Coastguard Worker 
26*288bf522SAndroid Build Coastguard Worker #define WARMUP (1<<10)
27*288bf522SAndroid Build Coastguard Worker 
28*288bf522SAndroid Build Coastguard Worker #define WORKLOAD (1<<24)
29*288bf522SAndroid Build Coastguard Worker 
30*288bf522SAndroid Build Coastguard Worker int numPagesList[] = {
31*288bf522SAndroid Build Coastguard Worker   1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
32*288bf522SAndroid Build Coastguard Worker   12, 14, 16, 18, 20, 24, 28, 30, 32, 34, 48, 62, 64, 66, 80,
33*288bf522SAndroid Build Coastguard Worker   96, 112, 128, 144, 160, 320, 480, 496, 512, 528, 544, 576, 640, 960,
34*288bf522SAndroid Build Coastguard Worker   1024, 2048, 3072, 4000,
35*288bf522SAndroid Build Coastguard Worker };
36*288bf522SAndroid Build Coastguard Worker 
stop_watch()37*288bf522SAndroid Build Coastguard Worker static unsigned long long stop_watch()
38*288bf522SAndroid Build Coastguard Worker {
39*288bf522SAndroid Build Coastguard Worker     struct timespec t;
40*288bf522SAndroid Build Coastguard Worker     t.tv_sec = t.tv_nsec = 0;
41*288bf522SAndroid Build Coastguard Worker     clock_gettime(CLOCK_MONOTONIC, &t);
42*288bf522SAndroid Build Coastguard Worker     return t.tv_sec*1000000000ULL + t.tv_nsec;
43*288bf522SAndroid Build Coastguard Worker }
44*288bf522SAndroid Build Coastguard Worker 
main()45*288bf522SAndroid Build Coastguard Worker int main()
46*288bf522SAndroid Build Coastguard Worker {
47*288bf522SAndroid Build Coastguard Worker     char *mem = malloc((N_PAGES+1) * 4096);
48*288bf522SAndroid Build Coastguard Worker     intptr_t *p;
49*288bf522SAndroid Build Coastguard Worker     int i;
50*288bf522SAndroid Build Coastguard Worker     unsigned int j;
51*288bf522SAndroid Build Coastguard Worker 
52*288bf522SAndroid Build Coastguard Worker     /* Align to page start */
53*288bf522SAndroid Build Coastguard Worker     mem = (char *) ((intptr_t) (mem + 4096) & ~0xfff);
54*288bf522SAndroid Build Coastguard Worker 
55*288bf522SAndroid Build Coastguard Worker     for (j = 0; j < sizeof(numPagesList)/sizeof(int); j++) {
56*288bf522SAndroid Build Coastguard Worker         int numPages = numPagesList[j];
57*288bf522SAndroid Build Coastguard Worker         int pageIdx = 0;
58*288bf522SAndroid Build Coastguard Worker         int entryOffset = 0;
59*288bf522SAndroid Build Coastguard Worker 
60*288bf522SAndroid Build Coastguard Worker         /*
61*288bf522SAndroid Build Coastguard Worker          * page 0      page 1      page 2     ....     page N
62*288bf522SAndroid Build Coastguard Worker          * ------      ------      ------              ------
63*288bf522SAndroid Build Coastguard Worker          * word 0   -> word 0   -> word 0 ->  ....  -> word 0 -> (page 0/word 0)
64*288bf522SAndroid Build Coastguard Worker          *   :           :           :         :         :
65*288bf522SAndroid Build Coastguard Worker          * word 1023   word 1023   word 1023   :       word 1023
66*288bf522SAndroid Build Coastguard Worker          */
67*288bf522SAndroid Build Coastguard Worker         for (i = 0; i < numPages; i++) {
68*288bf522SAndroid Build Coastguard Worker             int nextPageIdx = (pageIdx + 1) % numPages;
69*288bf522SAndroid Build Coastguard Worker             /* Looks like spread the pointer across cache lines introduce noise
70*288bf522SAndroid Build Coastguard Worker              * to get to the asymptote
71*288bf522SAndroid Build Coastguard Worker              * int nextEntryOffset = (entryOffset + 32) % 1024;
72*288bf522SAndroid Build Coastguard Worker              */
73*288bf522SAndroid Build Coastguard Worker             int nextEntryOffset = entryOffset;
74*288bf522SAndroid Build Coastguard Worker 
75*288bf522SAndroid Build Coastguard Worker             if (i != numPages -1) {
76*288bf522SAndroid Build Coastguard Worker                 *(intptr_t *) (mem + 4096 * pageIdx + entryOffset) =
77*288bf522SAndroid Build Coastguard Worker                     (intptr_t) (mem + 4096 * nextPageIdx + nextEntryOffset);
78*288bf522SAndroid Build Coastguard Worker             } else {
79*288bf522SAndroid Build Coastguard Worker                 /* Last page - form the cycle */
80*288bf522SAndroid Build Coastguard Worker                 *(intptr_t *) (mem + 4096 * pageIdx + entryOffset) =
81*288bf522SAndroid Build Coastguard Worker                     (intptr_t) &mem[0];
82*288bf522SAndroid Build Coastguard Worker             }
83*288bf522SAndroid Build Coastguard Worker 
84*288bf522SAndroid Build Coastguard Worker             pageIdx = nextPageIdx;
85*288bf522SAndroid Build Coastguard Worker             entryOffset = nextEntryOffset;
86*288bf522SAndroid Build Coastguard Worker         }
87*288bf522SAndroid Build Coastguard Worker 
88*288bf522SAndroid Build Coastguard Worker         /* Starting point of the pointer chase */
89*288bf522SAndroid Build Coastguard Worker         p = (intptr_t *) &mem[0];
90*288bf522SAndroid Build Coastguard Worker 
91*288bf522SAndroid Build Coastguard Worker         /* Warmup (ie pre-thrash the memory system */
92*288bf522SAndroid Build Coastguard Worker         for (i = 0; i < WARMUP; i++) {
93*288bf522SAndroid Build Coastguard Worker             p = (intptr_t *) *p;
94*288bf522SAndroid Build Coastguard Worker         }
95*288bf522SAndroid Build Coastguard Worker 
96*288bf522SAndroid Build Coastguard Worker         /* Real work */
97*288bf522SAndroid Build Coastguard Worker         unsigned long long t0 = stop_watch();
98*288bf522SAndroid Build Coastguard Worker         for (i = 0; i < WORKLOAD; i++) {
99*288bf522SAndroid Build Coastguard Worker             p = (intptr_t *) *p;
100*288bf522SAndroid Build Coastguard Worker         }
101*288bf522SAndroid Build Coastguard Worker         unsigned long long t1 = stop_watch();
102*288bf522SAndroid Build Coastguard Worker 
103*288bf522SAndroid Build Coastguard Worker         /* To keep p from being optimized by gcc */
104*288bf522SAndroid Build Coastguard Worker         if (p)
105*288bf522SAndroid Build Coastguard Worker             printf("%d, %f\n", numPages, (float) (t1 - t0) / WORKLOAD);
106*288bf522SAndroid Build Coastguard Worker     }
107*288bf522SAndroid Build Coastguard Worker     return 0;
108*288bf522SAndroid Build Coastguard Worker }
109