VirtualBox

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

Last change on this file since 94130 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 8.8 KB
Line 
1/* $Id: tstPrfRT.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * IPRT testcase - profile some of the important functions.
4 */
5
6/*
7 * Copyright (C) 2006-2022 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 RT_NOREF_PV(u64MaxTicks); RT_NOREF_PV(u64MinTicks);
68}
69
70# define ITERATE(preexpr, expr, postexpr, cIterations) \
71 AssertCompile(((cIterations) % 8) == 0); \
72 /* Min and max value. */ \
73 for (i = 0, u64MinTS = UINT64_MAX, u64MaxTS = 0; i < (cIterations); i++) \
74 { \
75 { preexpr } \
76 uint64_t u64StartTS = ASMReadTSC(); \
77 { expr } \
78 uint64_t u64ElapsedTS = ASMReadTSC() - u64StartTS; \
79 { postexpr } \
80 if (u64ElapsedTS > u64MinTS * 32) \
81 { \
82 i--; \
83 continue; \
84 } \
85 if (u64ElapsedTS < u64MinTS) \
86 u64MinTS = u64ElapsedTS; \
87 if (u64ElapsedTS > u64MaxTS) \
88 u64MaxTS = u64ElapsedTS; \
89 } \
90 { \
91 /* Calculate a good average value (may be smaller than min). */ \
92 i = (cIterations); \
93 AssertRelease((i % 8) == 0); \
94 { preexpr } \
95 uint64_t u64StartTS = ASMReadTSC(); \
96 while (i != 0) \
97 { \
98 { expr } \
99 { expr } \
100 { expr } \
101 { expr } \
102 { expr } \
103 { expr } \
104 { expr } \
105 { expr } \
106 i -= 8; \
107 } \
108 u64TotalTS = ASMReadTSC() - u64StartTS; \
109 { postexpr } \
110 i = (cIterations); \
111 }
112
113#else /* !AMD64 && !X86 */
114
115void PrintResult(uint64_t cNs, uint64_t cNsMax, uint64_t cNsMin, unsigned cTimes, const char *pszOperation)
116{
117 //RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS,
118 // "%-32s %5lld / %5lld / %5lld ns per call (%u calls %lld ns)\n",
119 // pszOperation, cNsMin, cNs / (uint64_t)cTimes, cNsMax, cTimes, cNs);
120 //RTTestValueF(g_hTest, cNsMin, RTTESTUNIT_NS_PER_CALL, "%s min", pszOperation);
121 RTTestValueF(g_hTest, cNs / (uint64_t)cTimes, RTTESTUNIT_NS_PER_CALL, "%s avg", pszOperation);
122 //RTTestValueF(g_hTest, cNsMax, RTTESTUNIT_NS_PER_CALL, "%s max", pszOperation);
123}
124
125# define ITERATE(preexpr, expr, postexpr, cIterations) \
126 for (i = 0, u64TotalTS = 0, u64MinTS = UINT64_MAX, u64MaxTS = 0; i < (cIterations); i++) \
127 { \
128 { preexpr } \
129 uint64_t u64StartTS = RTTimeNanoTS(); \
130 { expr } \
131 uint64_t u64ElapsedTS = RTTimeNanoTS() - u64StartTS; \
132 { postexpr } \
133 if (u64ElapsedTS > u64MinTS * 32) \
134 { \
135 i--; \
136 continue; \
137 } \
138 if (u64ElapsedTS < u64MinTS) \
139 u64MinTS = u64ElapsedTS; \
140 if (u64ElapsedTS > u64MaxTS) \
141 u64MaxTS = u64ElapsedTS; \
142 u64TotalTS += u64ElapsedTS; \
143 }
144
145#endif /* !AMD64 && !X86 */
146
147
148int main(int argc, char **argv)
149{
150 uint64_t u64TotalTS;
151 uint64_t u64MinTS;
152 uint64_t u64MaxTS;
153 uint32_t i;
154
155 RTEXITCODE rcExit = RTTestInitExAndCreate(argc, &argv, argc == 2 ? RTR3INIT_FLAGS_SUPLIB : 0, "tstRTPrf", &g_hTest);
156 if (rcExit != RTEXITCODE_SUCCESS)
157 return rcExit;
158 RTTestBanner(g_hTest);
159
160 /*
161 * RTTimeNanoTS, RTTimeProgramNanoTS, RTTimeMilliTS, and RTTimeProgramMilliTS.
162 */
163 ITERATE(RT_NOTHING, RTTimeNanoTS();, RT_NOTHING, _32M);
164 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTTimeNanoTS");
165
166 ITERATE(RT_NOTHING, RTTimeProgramNanoTS();, RT_NOTHING, UINT32_C(1000000));
167 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTTimeProgramNanoTS");
168
169 ITERATE(RT_NOTHING, RTTimeMilliTS();, RT_NOTHING, UINT32_C(1000000));
170 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTTimeMilliTS");
171
172 ITERATE(RT_NOTHING, RTTimeProgramMilliTS();, RT_NOTHING, UINT32_C(1000000));
173 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTTimeProgramMilliTS");
174
175 /*
176 * RTTimeNow
177 */
178 RTTIMESPEC Time;
179 ITERATE(RT_NOTHING, RTTimeNow(&Time);, RT_NOTHING, UINT32_C(1000000));
180 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTTimeNow");
181
182 /*
183 * RTLogDefaultInstance()
184 */
185 ITERATE(RT_NOTHING, RTLogDefaultInstance();, RT_NOTHING, UINT32_C(1000000));
186 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTLogDefaultInstance");
187
188 /*
189 * RTThreadSelf and RTThreadNativeSelf
190 */
191 ITERATE(RT_NOTHING, RTThreadSelf();, RT_NOTHING, UINT32_C(1000000));
192 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTThreadSelf");
193
194 ITERATE(RT_NOTHING, RTThreadNativeSelf();, RT_NOTHING, UINT32_C(1000000));
195 PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "RTThreadNativeSelf");
196
197#if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
198 /*
199 * Registers vs stack.
200 */
201 ITERATE(RT_NOTHING, tstRTPRfARegisterAccess();, RT_NOTHING, UINT32_C(1000));
202 uint64_t const cRegTotal = u64TotalTS;
203 //PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "Register only algorithm");
204
205 ITERATE(RT_NOTHING, tstRTPRfAMemoryAccess();, RT_NOTHING, UINT32_C(1000));
206 uint64_t const cMemTotal = u64TotalTS;
207 //PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "Memory only algorithm");
208
209 ITERATE(RT_NOTHING, tstRTPRfAMemoryUnalignedAccess();, RT_NOTHING, UINT32_C(1000));
210 uint64_t const cMemUnalignedTotal = u64TotalTS;
211 //PrintResult(u64TotalTS, u64MaxTS, u64MinTS, i, "Memory only algorithm");
212
213 uint64_t const cSlower100 = cMemTotal * 100 / cRegTotal;
214 RTTestValue(g_hTest, "Memory instead of registers slowdown", cSlower100, RTTESTUNIT_PCT);
215 uint64_t const cUnalignedSlower100 = cMemUnalignedTotal * 100 / cRegTotal;
216 RTTestValue(g_hTest, "Unaligned memory instead of registers slowdown", cUnalignedSlower100, RTTESTUNIT_PCT);
217#endif
218
219 return RTTestSummaryAndDestroy(g_hTest);
220}
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