• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  * Atomic operation performance test.
19  */
20 #include "Dalvik.h"
21 
22 //#define TRIVIAL_COMPARE     /* do something simple instead of an atomic op */
23 
24 /*
25  * Perform operation.  Returns elapsed time.
26  */
dvmTestAtomicSpeedSub(int repeatCount)27 u8 dvmTestAtomicSpeedSub(int repeatCount)
28 {
29     static int value = 7;
30     int* valuePtr = &value;
31     u8 start, end;
32     int i;
33 
34 #ifdef TRIVIAL_COMPARE
35     /* init to arg value so compiler can't pre-determine result */
36     int j = repeatCount;
37 #endif
38 
39     assert((repeatCount % 10) == 0);
40 
41     start = dvmGetRelativeTimeNsec();
42 
43     for (i = repeatCount / 10; i != 0; i--) {
44 #ifdef TRIVIAL_COMPARE
45         // integer add (Dream: 3.4ns -- THUMB has 10 adds, ARM condenses)
46         j += i; j += i; j += i; j += i; j += i;
47         j += i; j += i; j += i; j += i; j += i;
48 #else
49         // succeed 10x (Dream: 155.9ns)
50         ATOMIC_CMP_SWAP(valuePtr, 7, 7);
51         ATOMIC_CMP_SWAP(valuePtr, 7, 7);
52         ATOMIC_CMP_SWAP(valuePtr, 7, 7);
53         ATOMIC_CMP_SWAP(valuePtr, 7, 7);
54         ATOMIC_CMP_SWAP(valuePtr, 7, 7);
55         ATOMIC_CMP_SWAP(valuePtr, 7, 7);
56         ATOMIC_CMP_SWAP(valuePtr, 7, 7);
57         ATOMIC_CMP_SWAP(valuePtr, 7, 7);
58         ATOMIC_CMP_SWAP(valuePtr, 7, 7);
59         ATOMIC_CMP_SWAP(valuePtr, 7, 7);
60 
61         // fail 10x (Dream: 158.5ns)
62         /*
63         ATOMIC_CMP_SWAP(valuePtr, 6, 7);
64         ATOMIC_CMP_SWAP(valuePtr, 6, 7);
65         ATOMIC_CMP_SWAP(valuePtr, 6, 7);
66         ATOMIC_CMP_SWAP(valuePtr, 6, 7);
67         ATOMIC_CMP_SWAP(valuePtr, 6, 7);
68         ATOMIC_CMP_SWAP(valuePtr, 6, 7);
69         ATOMIC_CMP_SWAP(valuePtr, 6, 7);
70         ATOMIC_CMP_SWAP(valuePtr, 6, 7);
71         ATOMIC_CMP_SWAP(valuePtr, 6, 7);
72         ATOMIC_CMP_SWAP(valuePtr, 6, 7);
73         */
74 #endif
75     }
76 
77     end = dvmGetRelativeTimeNsec();
78 
79 #ifdef TRIVIAL_COMPARE
80     /* use value so compiler can't eliminate it */
81     dvmFprintf(stdout, "%d\n", j);
82 #else
83     dvmFprintf(stdout, ".");
84     fflush(stdout);     // not quite right if they intercepted fprintf
85 #endif
86     return end - start;
87 }
88 
89 /*
90  * Control loop.
91  */
dvmTestAtomicSpeed(void)92 bool dvmTestAtomicSpeed(void)
93 {
94     static const int kIterations = 10;
95     static const int kRepeatCount = 5 * 1000 * 1000;
96     static const int kDelay = 500 * 1000;
97     u8 results[kIterations];
98     int i;
99 
100     for (i = 0; i < kIterations; i++) {
101         results[i] = dvmTestAtomicSpeedSub(kRepeatCount);
102         usleep(kDelay);
103     }
104 
105     dvmFprintf(stdout, "\n");
106     dvmFprintf(stdout, "Atomic speed test results (%d per iteration):\n",
107         kRepeatCount);
108     for (i = 0; i < kIterations; i++) {
109         dvmFprintf(stdout,
110             " %2d: %.3fns\n", i, (double) results[i] / kRepeatCount);
111     }
112 
113     return true;
114 }
115 
116