From d37b4c8126033fe9dd665509bf0743eb0fd67a7a Mon Sep 17 00:00:00 2001 From: Ben Cheng Date: Fri, 26 Feb 2010 13:57:49 -0800 Subject: 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. --- tests/pftest/Android.mk | 18 ++++++++ tests/pftest/pftest.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 tests/pftest/Android.mk create mode 100644 tests/pftest/pftest.c (limited to 'tests/pftest') 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 +#include +#include +#include +#include +#include + +#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; +} -- cgit v1.2.3