C++程序  |  116行  |  3.19 KB

/*
 * 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;
}