VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstPrfRT.cpp@ 60191

Last change on this file since 60191 was 60191, checked in by vboxsync, 9 years ago

tstRTPrf: Converted to iprt/test.h and added a little off topic comparison between CPU register and memory based code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 8.6 KB
Line 
1/* $Id: tstPrfRT.cpp 60191 2016-03-25 16:59:31Z vboxsync $ */
2/** @file
3 * IPRT testcase - profile some of the important functions.
4 */
5
6/*
7 * Copyright (C) 2006-2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/initterm.h>
32#include <iprt/time.h>
33#include <iprt/log.h>
34#include <iprt/test.h>
35#include <iprt/thread.h>
36#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
37# include <iprt/asm-amd64-x86.h>
38#endif
39
40
41/*********************************************************************************************************************************
42* Internal Functions *
43*********************************************************************************************************************************/
44#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
45DECLASM(void) tstRTPRfAMemoryAccess(void);
46DECLASM(void) tstRTPRfARegisterAccess(void);
47DECLASM(void) tstRTPRfAMemoryUnalignedAccess(void);
48#endif
49
50
51/*********************************************************************************************************************************
52* Global Variables *
53*********************************************************************************************************************************/
54static RTTEST g_hTest;
55
56
57#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
58
59void PrintResult(uint64_t u64Ticks, uint64_t u64MaxTicks, uint64_t u64MinTicks, unsigned cTimes, const char *pszOperation)
60{
61 //RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS,
62 // "%-32s %5lld / %5lld / %5lld ticks per call (%u calls %lld ticks)\n",
63 // pszOperation, u64MinTicks, u64Ticks / (uint64_t)cTimes, u64MaxTicks, cTimes, u64Ticks);
64 //RTTestValueF(g_hTest, u64MinTicks, RTTESTUNIT_NONE, "%s min ticks", pszOperation);
65 RTTestValueF(g_hTest, u64Ticks / (uint64_t)cTimes, RTTESTUNIT_NONE, "%s avg ticks", pszOperation);
66 //RTTestValueF(g_hTest, u64MaxTicks, RTTESTUNIT_NONE, "%s max ticks", pszOperation);
67}
68
69# define ITERATE(preexpr, expr, postexpr, cIterations) \
70 AssertCompile(((cIterations) % 8) == 0); \
71 /* Min and max value. */ \
72 for (i = 0, u64MinTS = ~0, u64MaxTS = 0; i < (cIterations); i++) \
73 { \
74 { preexpr } \
75 uint64_t u64StartTS = ASMReadTSC(); \
76 { expr } \
77 uint64_t u64ElapsedTS = ASMReadTSC() - u64StartTS; \
78 { postexpr } \
79 if (u64ElapsedTS > u64MinTS * 32) \
80 { \
81 i--; \
82 continue; \
83 } \
84 if (u64ElapsedTS < u64MinTS) \
85 u64MinTS = u64ElapsedTS; \
86 if (u64ElapsedTS > u64MaxTS) \
87 u64MaxTS = u64ElapsedTS; \
88 } \
89 { \
90 /* Calculate a good average value (may be smaller than min). */ \
91 i = (cIterations); \
92 AssertRelease((i % 8) == 0); \
93 { preexpr } \
94 uint64_t u64StartTS = ASMReadTSC(); \
95 while (i != 0) \
96 { \
97 { expr } \
98 { expr } \
99 { expr } \
100 { expr } \
101 { expr } \
102 { expr } \
103 { expr } \
104 { expr } \
105 i -= 8; \
106 } \
107 u64TotalTS = ASMReadTSC() - u64StartTS; \
108 { postexpr } \
109 i = (cIterations); \
110 }
111
112#else /* !AMD64 && !X86 */
113
114void PrintResult(uint64_t cNs, uint64_t cNsMax, uint64_t cNsMin, unsigned cTimes, const char *pszOperation)
115{
116 //RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS,
117 // "%-32s %5lld / %5lld / %5lld ns per call (%u calls %lld ns)\n",
118 // pszOperation, cNsMin, cNs / (uint64_t)cTimes, cNsMax, cTimes, cNs);
119 //RTTestValueF(g_hTest, cNsMin, RTTESTUNIT_NS_PER_CALL, "%s min", pszOperation);
120 RTTestValueF(g_hTest, cNs / (uint64_t)cTimes, RTTESTUNIT_NS_PER_CALL, "%s avg", pszOperation);
121 //RTTestValueF(g_hTest, cNsMax, RTTESTUNIT_NS_PER_CALL, "%s max", pszOperation);
122}
123
124# define ITERATE(preexpr, expr, postexpr, cIterations) \
125 for (i = 0, u64TotalTS = 0, u64MinTS = ~0, u64MaxTS = 0; i < (cIterations); i++) \
126 { \
127 { preexpr } \
128 uint64_t u64StartTS = RTTimeNanoTS(); \
129 { expr } \
130 uint64_t u64ElapsedTS = RTTimeNanoTS() - u64StartTS; \
131 { postexpr } \
132 if (u64ElapsedTS > u64MinTS * 32) \
133 { \
134 i--; \
135 continue; \
136 } \
137 if (u64ElapsedTS < u64MinTS) \
138 u64MinTS = u64ElapsedTS; \
139 if (u64ElapsedTS > u64MaxTS) \
140 u64MaxTS = u64ElapsedTS; \
141 u64TotalTS += u64ElapsedTS; \
142 }
143
144#endif /* !AMD64 && !X86 */
145
146
147int main(int argc, char **argv)
148{
149 uint64_t u64TotalTS;
150 uint64_t u64MinTS;
151 uint64_t u64MaxTS;
152 unsigned i;
153
154 RTEXITCODE rcExit = RTTestInitExAndCreate(argc, &argv, argc == 2 ? RTR3INIT_FLAGS_SUPLIB : 0, "tstRTPrf", &g_hTest);
155 if (rcExit != RTEXITCODE_SUCCESS)
156 return rcExit;
157 RTTestBanner(g_hTest);
158
159 /*
160 * RTTimeNanoTS, RTTimeProgramNanoTS, RTTimeMilliTS, and RTTimeProgramMilliTS.
161 */
162 ITERATE(RT_NOTHING, RTTimeNanoTS();, RT_NOTHING, _1M * 32);
163 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTTimeNanoTS");
164
165 ITERATE(RT_NOTHING, RTTimeProgramNanoTS();, RT_NOTHING, 1000000);
166 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTTimeProgramNanoTS");
167
168 ITERATE(RT_NOTHING, RTTimeMilliTS();, RT_NOTHING, 1000000);
169 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTTimeMilliTS");
170
171 ITERATE(RT_NOTHING, RTTimeProgramMilliTS();, RT_NOTHING, 1000000);
172 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTTimeProgramMilliTS");
173
174 /*
175 * RTTimeNow
176 */
177 RTTIMESPEC Time;
178 ITERATE(RT_NOTHING, RTTimeNow(&Time);, RT_NOTHING, 1000000);
179 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTTimeNow");
180
181 /*
182 * RTLogDefaultInstance()
183 */
184 ITERATE(RT_NOTHING, RTLogDefaultInstance();, RT_NOTHING, 1000000);
185 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTLogDefaultInstance");
186
187 /*
188 * RTThreadSelf and RTThreadNativeSelf
189 */
190 ITERATE(RT_NOTHING, RTThreadSelf();, RT_NOTHING, 1000000);
191 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTThreadSelf");
192
193 ITERATE(RT_NOTHING, RTThreadNativeSelf();, RT_NOTHING, 1000000);
194 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTThreadNativeSelf");
195
196#if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
197 /*
198 * Registers vs stack.
199 */
200 ITERATE(RT_NOTHING, tstRTPRfARegisterAccess();, RT_NOTHING, 1000);
201 uint64_t const cRegTotal = u64TotalTS;
202 //PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "Register only algorithm");
203
204 ITERATE(RT_NOTHING, tstRTPRfAMemoryAccess();, RT_NOTHING, 1000);
205 uint64_t const cMemTotal = u64TotalTS;
206 //PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "Memory only algorithm");
207
208 ITERATE(RT_NOTHING, tstRTPRfAMemoryUnalignedAccess();, RT_NOTHING, 1000);
209 uint64_t const cMemUnalignedTotal = u64TotalTS;
210 //PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "Memory only algorithm");
211
212 uint64_t const cSlower100 = cMemTotal * 100 / cRegTotal;
213 RTTestValue(g_hTest, "Memory instead of registers slowdown", cSlower100, RTTESTUNIT_PCT);
214 uint64_t const cUnalignedSlower100 = cMemUnalignedTotal * 100 / cRegTotal;
215 RTTestValue(g_hTest, "Unaligned memory instead of registers slowdown", cUnalignedSlower100, RTTESTUNIT_PCT);
216#endif
217
218 return RTTestSummaryAndDestroy(g_hTest);
219}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette