summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Cheng <bccheng@android.com>2010-02-26 13:57:49 -0800
committerBen Cheng <bccheng@android.com>2010-02-26 13:57:49 -0800
commitd37b4c8126033fe9dd665509bf0743eb0fd67a7a (patch)
treef83c004cd62db5b4ff07de8381f361a30ccc253c
parent431ccc3e7f8540da36a8d07128a0c976918436b9 (diff)
downloadextras-d37b4c8126033fe9dd665509bf0743eb0fd67a7a.tar.gz
New test to shmoo the size of the working set against the memory system.
Find out the sweet spot of the paging system and approximate the page fault latency.
-rw-r--r--tests/pftest/Android.mk18
-rw-r--r--tests/pftest/pftest.c108
2 files changed, 126 insertions, 0 deletions
diff --git a/tests/pftest/Android.mk b/tests/pftest/Android.mk
new file mode 100644
index 00000000..bedbd0cb
--- /dev/null
+++ b/tests/pftest/Android.mk
@@ -0,0 +1,18 @@
+# Copyright 2010 The Android Open Source Project
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= pftest.c.arm
+
+
+LOCAL_SHARED_LIBRARIES := libc
+
+LOCAL_MODULE:= pftest
+
+LOCAL_MODULE_TAGS := optional
+
+## LOCAL_CFLAGS += -fstack-protector-all
+LOCAL_CFLAGS += -fomit-frame-pointer
+
+include $(BUILD_EXECUTABLE)
diff --git a/tests/pftest/pftest.c b/tests/pftest/pftest.c
new file mode 100644
index 00000000..f5af8947
--- /dev/null
+++ b/tests/pftest/pftest.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+
+#define N_PAGES (4096)
+
+#define WARMUP (1<<10)
+
+#define WORKLOAD (1<<24)
+
+int numPagesList[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 12, 14, 16, 18, 20, 24, 28, 30, 32, 34, 48, 62, 64, 66, 80,
+ 96, 112, 128, 144, 160, 320, 480, 496, 512, 528, 544, 576, 640, 960,
+ 1024, 2048, 3072, 4000,
+};
+
+static unsigned long long stop_watch()
+{
+ struct timespec t;
+ t.tv_sec = t.tv_nsec = 0;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ return t.tv_sec*1000000000ULL + t.tv_nsec;
+}
+
+int main()
+{
+ char *mem = malloc((N_PAGES+1) * 4096);
+ intptr_t *p;
+ int i;
+ unsigned int j;
+
+ /* Align to page start */
+ mem = (char *) ((intptr_t) (mem + 4096) & ~0xfff);
+
+ for (j = 0; j < sizeof(numPagesList)/sizeof(int); j++) {
+ int numPages = numPagesList[j];
+ int pageIdx = 0;
+ int entryOffset = 0;
+
+ /*
+ * page 0 page 1 page 2 .... page N
+ * ------ ------ ------ ------
+ * word 0 -> word 0 -> word 0 -> .... -> word 0 -> (page 0/word 0)
+ * : : : : :
+ * word 1023 word 1023 word 1023 : word 1023
+ */
+ for (i = 0; i < numPages; i++) {
+ int nextPageIdx = (pageIdx + 1) % numPages;
+ /* Looks like spread the pointer across cache lines introduce noise
+ * to get to the asymptote
+ * int nextEntryOffset = (entryOffset + 32) % 1024;
+ */
+ int nextEntryOffset = entryOffset;
+
+ if (i != numPages -1) {
+ *(intptr_t *) (mem + 4096 * pageIdx + entryOffset) =
+ (intptr_t) (mem + 4096 * nextPageIdx + nextEntryOffset);
+ } else {
+ /* Last page - form the cycle */
+ *(intptr_t *) (mem + 4096 * pageIdx + entryOffset) =
+ (intptr_t) &mem[0];
+ }
+
+ pageIdx = nextPageIdx;
+ entryOffset = nextEntryOffset;
+ }
+
+ /* Starting point of the pointer chase */
+ p = (intptr_t *) &mem[0];
+
+ /* Warmup (ie pre-thrash the memory system */
+ for (i = 0; i < WARMUP; i++) {
+ p = (intptr_t *) *p;
+ }
+
+ /* Real work */
+ unsigned long long t0 = stop_watch();
+ for (i = 0; i < WORKLOAD; i++) {
+ p = (intptr_t *) *p;
+ }
+ unsigned long long t1 = stop_watch();
+
+ /* To keep p from being optimized by gcc */
+ if (p)
+ printf("%d, %f\n", numPages, (float) (t1 - t0) / WORKLOAD);
+ }
+ return 0;
+}