First public contribution.
1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\bench\t_asmbm.cpp
24 const TReal KDefaultRunLength = 1.0;
25 const TInt KInitIterations = 3000;
27 // Length of time to run benchmark for in seconds
28 TReal RunLength = KDefaultRunLength;
30 TInt FastCounterFrequency;
31 TBool FastCounterCountsUp;
34 * Calculate the time in seconds corresponding to a fast counter delta value.
36 TReal TimeDelta(TInt aDelta)
38 if (!FastCounterCountsUp)
40 return ((TReal) aDelta + 1) / FastCounterFrequency;
44 * Run a benchmark for the specifiec number of iterations and return the total
45 * time taken in seconds.
47 TReal TimeBenchmarkL(MBenchmarkList& aBenchmarks, TInt aIndex, const TBmParams& aParams)
50 User::LeaveIfError(aBenchmarks.Run(aIndex, aParams, delta));
51 User::After(20 * 1000); // hack: wait for kernel thread to exit
52 return TimeDelta(delta);
55 void RunGeneralBenchmarkL(MBenchmarkList& aBenchmarks, TInt aIndex, const TBmInfo& aInfo)
57 // Run the benchmark with a small number of iterations and from this result
58 // work out how many iterations we need to run it for RunLength seconds.
59 // Loop till we get it right.
62 params.iSourceAlign = 0;
63 params.iDestAlign = 0;
65 TInt iterations = KInitIterations;
69 params.iIts = iterations / 10;
70 time = TimeBenchmarkL(aBenchmarks, aIndex, params);
71 if (time >= RunLength)
73 iterations = (TInt) ((RunLength * 1.2) / (time/(TReal)iterations));
77 nameBuf.Copy(aInfo.iName);
78 test.Printf(_L("%i\t%e\t%S\n"), aIndex, time/iterations * 1000000.0, &nameBuf);
81 void RunMemoryBenchmarkL(MBenchmarkList& aBenchmarks, TInt aIndex, const TBmInfo& aInfo)
83 // Run the benchmark with a small number of iterations and from this result
84 // work out how many iterations we need to run it for RunLength seconds.
85 // Loop till we get it right.
88 params.iSourceAlign = 0;
89 params.iDestAlign = 0;
91 TInt iterations = KInitIterations;
95 params.iIts = iterations / 10;
96 time = TimeBenchmarkL(aBenchmarks, aIndex, params);
97 if (time >= RunLength)
99 iterations = (TInt) ((RunLength * 1.2) / (time/(TReal)iterations));
103 nameBuf.Copy(aInfo.iName);
104 test.Printf(_L("%i\t%S\talignment step == %d\n"), aIndex, &nameBuf, aInfo.iAlignStep);
106 for (TInt sourceAlign = 0 ; sourceAlign < 32 ; sourceAlign += aInfo.iAlignStep)
108 for (TInt destAlign = 0 ; destAlign < 32 ; destAlign += aInfo.iAlignStep)
110 params.iSourceAlign = sourceAlign;
111 params.iDestAlign = destAlign;
112 time = TimeBenchmarkL(aBenchmarks, aIndex, params);
113 test.Printf(_L("%e\t"), time/iterations * 1000000.0);
115 test.Printf(_L("\n"));
119 void RunBenchmarkL(MBenchmarkList& aBenchmarks, TInt aIndex, TUint aCategories)
122 User::LeaveIfError(aBenchmarks.Info(aIndex, info));
124 if (!(info.iCategories & aCategories))
127 if (info.iCategories & aCategories & KCategoryMemory)
128 RunMemoryBenchmarkL(aBenchmarks, aIndex, info);
130 RunGeneralBenchmarkL(aBenchmarks, aIndex, info);
135 test.Printf(_L("usage: [ OPTIONS ] [ INDEX... ]\n"));
136 test.Printf(_L("Options are:\n"));
137 test.Printf(_L(" -r TIME Set the length of time in seconds to run each benchmark for\n"));
138 test.Printf(_L(" -m Run memory alignment benchmarks only\n"));
139 test.Printf(_L(" -x Run extra benchmarks as well as normal ones\n"));
142 void RunBenchmarkTestsL(MBenchmarkList& aBenchmarks)
146 User::LeaveIfError(HAL::Get(HALData::EFastCounterFrequency, FastCounterFrequency));
147 User::LeaveIfError(HAL::Get(HALData::EFastCounterCountsUp, FastCounterCountsUp));
149 TInt count = aBenchmarks.Count();
151 TUint categories = KCategoryGeneral;
153 RArray<TInt> testsToRun;
154 CleanupClosePushL(testsToRun);
156 HBufC* buf = HBufC::NewLC(User::CommandLineLength());
157 TPtr ptr = buf->Des();
158 User::CommandLine(ptr);
160 if (ptr != KNullDesC)
165 while (ok && (token.Set(lex.NextToken()), token != KNullDesC))
167 if (token == _L("-r"))
169 token.Set(lex.NextToken());
170 if (token == KNullDesC ||
171 TLex(token).Val(RunLength) != KErrNone ||
178 else if (token == _L("-m"))
180 categories = KCategoryMemory;
182 else if (token == _L("-x"))
184 categories = KCategoryGeneral | KCategoryExtra;
189 if (TLex(token).Val(index) != KErrNone)
194 else if (index < 0 || index >= count)
196 test.Printf(_L("Index out of range: %d\n"), index);
201 testsToRun.AppendL(index);
207 CleanupStack::PopAndDestroy(buf);
211 test.Printf(_L("Note that these benchmarks are intended to guide optimisation, and not to\n"));
212 test.Printf(_L("provide a meaningful indication of the speed of specific functions\n"));
213 test.Printf(_L("\n"));
214 if (testsToRun.Count() == 0)
216 for (TInt i = 0 ; i < count ; ++i)
218 RunBenchmarkL(aBenchmarks, i, categories);
223 for (TInt i = 0 ; i < testsToRun.Count() ; ++i)
225 RunBenchmarkL(aBenchmarks, testsToRun[i], categories);
230 CleanupStack::PopAndDestroy(&testsToRun);