/* * Copyright (C) 2009 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. */ /* * Atomic operation performance test. */ #include "Dalvik.h" //#define TRIVIAL_COMPARE /* do something simple instead of an atomic op */ /* * Perform operation. Returns elapsed time. */ u8 dvmTestAtomicSpeedSub(int repeatCount) { static int value = 7; int* valuePtr = &value; u8 start, end; int i; #ifdef TRIVIAL_COMPARE /* init to arg value so compiler can't pre-determine result */ int j = repeatCount; #endif assert((repeatCount % 10) == 0); start = dvmGetRelativeTimeNsec(); for (i = repeatCount / 10; i != 0; i--) { #ifdef TRIVIAL_COMPARE // integer add (Dream: 3.4ns -- THUMB has 10 adds, ARM condenses) j += i; j += i; j += i; j += i; j += i; j += i; j += i; j += i; j += i; j += i; #else // succeed 10x (Dream: 155.9ns) ATOMIC_CMP_SWAP(valuePtr, 7, 7); ATOMIC_CMP_SWAP(valuePtr, 7, 7); ATOMIC_CMP_SWAP(valuePtr, 7, 7); ATOMIC_CMP_SWAP(valuePtr, 7, 7); ATOMIC_CMP_SWAP(valuePtr, 7, 7); ATOMIC_CMP_SWAP(valuePtr, 7, 7); ATOMIC_CMP_SWAP(valuePtr, 7, 7); ATOMIC_CMP_SWAP(valuePtr, 7, 7); ATOMIC_CMP_SWAP(valuePtr, 7, 7); ATOMIC_CMP_SWAP(valuePtr, 7, 7); // fail 10x (Dream: 158.5ns) /* ATOMIC_CMP_SWAP(valuePtr, 6, 7); ATOMIC_CMP_SWAP(valuePtr, 6, 7); ATOMIC_CMP_SWAP(valuePtr, 6, 7); ATOMIC_CMP_SWAP(valuePtr, 6, 7); ATOMIC_CMP_SWAP(valuePtr, 6, 7); ATOMIC_CMP_SWAP(valuePtr, 6, 7); ATOMIC_CMP_SWAP(valuePtr, 6, 7); ATOMIC_CMP_SWAP(valuePtr, 6, 7); ATOMIC_CMP_SWAP(valuePtr, 6, 7); ATOMIC_CMP_SWAP(valuePtr, 6, 7); */ #endif } end = dvmGetRelativeTimeNsec(); #ifdef TRIVIAL_COMPARE /* use value so compiler can't eliminate it */ dvmFprintf(stdout, "%d\n", j); #else dvmFprintf(stdout, "."); fflush(stdout); // not quite right if they intercepted fprintf #endif return end - start; } /* * Control loop. */ bool dvmTestAtomicSpeed(void) { static const int kIterations = 10; static const int kRepeatCount = 5 * 1000 * 1000; static const int kDelay = 500 * 1000; u8 results[kIterations]; int i; for (i = 0; i < kIterations; i++) { results[i] = dvmTestAtomicSpeedSub(kRepeatCount); usleep(kDelay); } dvmFprintf(stdout, "\n"); dvmFprintf(stdout, "Atomic speed test results (%d per iteration):\n", kRepeatCount); for (i = 0; i < kIterations; i++) { dvmFprintf(stdout, " %2d: %.3fns\n", i, (double) results[i] / kRepeatCount); } return true; }