1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/bench/t_membm.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,227 @@
1.4 +// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\bench\t_membm.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include <e32std.h>
1.22 +#include <e32std_private.h>
1.23 +#include <e32base.h>
1.24 +#include <e32base_private.h>
1.25 +#include <e32test.h>
1.26 +#include <e32svr.h>
1.27 +
1.28 +#define ALIGN_UP(x, y) (TInt8*)(_ALIGN_UP((TInt)(x), (y)))
1.29 +#define ALIGN_DOWN(x, y) (TInt8*)(_ALIGN_DOWN((TInt)(x), (y)))
1.30 +
1.31 +const TInt KHeapSize=720*1024;
1.32 +const TInt KAverageOverInMilliseconds=500;
1.33 +const TInt Len64K = 64*1024;
1.34 +
1.35 +volatile TInt count;
1.36 +volatile TInt iters;
1.37 +
1.38 +TInt8* trg;
1.39 +TInt8* src;
1.40 +TInt8* dummy;
1.41 +TInt8 trgoffset;
1.42 +TInt8 srcoffset;
1.43 +TInt len=64*1024;
1.44 +TInt64 result;
1.45 +
1.46 +RTest test(_L("T_MEMBM"));
1.47 +
1.48 +GLREF_C TInt MemBaseline(TAny*);
1.49 +GLREF_C TInt MemCopy(TAny*);
1.50 +GLREF_C TInt MemMove(TAny*);
1.51 +GLREF_C TInt MemFill(TAny*);
1.52 +GLREF_C TInt MemSwap(TAny*);
1.53 +GLREF_C TInt WordMove(TAny*);
1.54 +GLREF_C TInt MemCopyUncached(TAny*);
1.55 +GLREF_C TInt WordMoveUncached(TAny*);
1.56 +GLREF_C TInt MemFillUncached(TAny*);
1.57 +GLREF_C TInt PurgeCache();
1.58 +
1.59 +TInt nextLen(TInt aTestLength)
1.60 + {
1.61 + if (len == Len64K)
1.62 + return 0;
1.63 + if (!aTestLength)
1.64 + return Len64K;
1.65 +
1.66 + TInt inc = aTestLength;
1.67 + for (TInt i = len >> 5 ; i ; i >>= 1)
1.68 + inc <<= 1;
1.69 +
1.70 + return len + inc;
1.71 + }
1.72 +
1.73 +/**
1.74 + * Run benchmarks on the supplied function.
1.75 + *
1.76 + * @param aFunction The function to benchmark
1.77 + * @param aTestBackwards Run copy tests with overlapping areas to test backwards copy
1.78 + * @param aTestSrcAlign Run tests for source alignments 0 - 31
1.79 + * @param aTestDestAlign Run tests for destination alignments 0 - 31
1.80 + * @param aTestLength If non-zero, run tests for different lengths starting at aTestLength
1.81 + */
1.82 +TInt64 runTest(TThreadFunction aFunction,const TDesC& aTitle, TBool aTestBackwards, TBool aTestSrcAlign, TBool aTestDestAlign, TInt aTestLength)
1.83 + {
1.84 + TInt8* buffer = (TInt8*)User::Alloc(640 * 1024 + 32);
1.85 + test(buffer != 0);
1.86 +
1.87 + test(!(aTestLength && aTestBackwards)); // not supported
1.88 +
1.89 + TBool goingforward=ETrue;
1.90 +
1.91 + FOREVER
1.92 + {
1.93 + if (aTestLength)
1.94 + test.Printf(_L("Running length experiment on %S. Results follow:\n"), &aTitle);
1.95 +
1.96 + len = 0;
1.97 + while(len = nextLen(aTestLength), len)
1.98 + {
1.99 + src = ALIGN_UP(buffer, 32);
1.100 + if (goingforward)
1.101 + trg = src + 512 * 1024; // blow half a meg
1.102 + else
1.103 + trg = ALIGN_DOWN(src + len - 1, 32); // ensure overlapping, doesn't work for length < 32
1.104 +
1.105 + if (aTestLength)
1.106 + test.Printf(_L("%d, "), len);
1.107 + else
1.108 + test.Printf(_L("Test array bases trg=0x%08x, src=0x%08x. Running experiment on %S. Results follow:\n"), trg, src, &aTitle);
1.109 +
1.110 + const TInt xsquare = aTestDestAlign ? 32 : 1;
1.111 + const TInt ysquare = aTestSrcAlign ? 32 : 1;
1.112 +
1.113 + for (srcoffset = 0 ; srcoffset < ysquare ; srcoffset++)
1.114 + {
1.115 + for (trgoffset = 0 ; trgoffset < xsquare ; trgoffset++)
1.116 + {
1.117 + RThread thread;
1.118 + TInt r=thread.Create(aTitle,aFunction,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
1.119 + if(r!=KErrNone)
1.120 + {
1.121 + test.Printf(_L("Failed to create thread with error %d\n"),r);
1.122 + return(r);
1.123 + }
1.124 + thread.SetPriority(EPriorityLess);
1.125 + thread.Resume();
1.126 + User::After(50000); // 50 msec is more than enough in EKA2
1.127 + count=0;
1.128 + User::After(5000); // even if the second reset fails, max inaccuracy is 5000 usecs
1.129 + count=0; // try and reduce the probability of failing to reset
1.130 + User::After(KAverageOverInMilliseconds*1000);
1.131 + result=count;
1.132 + thread.Kill(0);
1.133 + CLOSE_AND_WAIT(thread);
1.134 + PurgeCache();
1.135 +
1.136 + result *= 1000;
1.137 + result /= KAverageOverInMilliseconds;
1.138 +
1.139 + TInt s = I64INT(result);
1.140 + test.Printf(_L("%d, "),s);
1.141 + }
1.142 + test.Printf(_L("\n"));
1.143 + }
1.144 + }
1.145 +
1.146 + if (aTestBackwards && goingforward)
1.147 + goingforward = EFalse;
1.148 + else
1.149 + break;
1.150 + }
1.151 +
1.152 + User::Free(buffer);
1.153 +
1.154 + return(result);
1.155 + }
1.156 +
1.157 +enum TTestType
1.158 + {
1.159 + ENormalTests,
1.160 + EFullTests,
1.161 + ELengthTests,
1.162 + };
1.163 +
1.164 +// Return whether we should run the full alignment benchmarks
1.165 +TTestType ParseCommandLine()
1.166 + {
1.167 + TBuf<32> args;
1.168 + User::CommandLine(args);
1.169 +
1.170 + if (args == _L("-f"))
1.171 + return EFullTests;
1.172 + else if (args == _L("-l"))
1.173 + return ELengthTests;
1.174 + else if (args != KNullDesC)
1.175 + {
1.176 + test.Printf(_L("usage: t_membm [OPTIONS]\n"));
1.177 + test.Printf(_L(" -f Run full alignment benchmarks\n"));
1.178 + test.Printf(_L(" -l Run memcpy length benchmarks\n"));
1.179 + test(EFalse);
1.180 + }
1.181 +
1.182 + return ENormalTests;
1.183 + }
1.184 +
1.185 +TInt E32Main()
1.186 +//
1.187 +// Benchmark for Mem functions
1.188 +//
1.189 + {
1.190 +
1.191 + test.Title();
1.192 + test.Start(_L("Benchmarks for Mem functions"));
1.193 +
1.194 + TTestType testType = ParseCommandLine();
1.195 +
1.196 + switch (testType)
1.197 + {
1.198 + case ENormalTests:
1.199 + case EFullTests:
1.200 + {
1.201 + TBool srcAlign = testType == EFullTests;
1.202 +
1.203 + if (srcAlign)
1.204 + test.Printf(_L("Running full alignment benchmarks (may take a long time)\n"));
1.205 + else
1.206 + test.Printf(_L("Not testing source alignment (run with -f if you want this)\n"));
1.207 +
1.208 + runTest(MemBaseline, _L("Processor baseline"), EFalse, EFalse, EFalse, 0);
1.209 + runTest(MemFill, _L("Memory fill"), EFalse, EFalse, ETrue, 0);
1.210 + runTest(MemCopy, _L("Memory copy"), ETrue, srcAlign, ETrue, 0);
1.211 + runTest(MemSwap, _L("Memory swap"), ETrue, srcAlign, ETrue, 0);
1.212 + }
1.213 + break;
1.214 + case ELengthTests:
1.215 + test.Printf(_L("Running length benchmarks (may take a long time)\n"));
1.216 + runTest(MemFill, _L("Fill length cached"), EFalse, EFalse, EFalse, 1);
1.217 + runTest(MemFillUncached, _L("Fill length uncached"), EFalse, EFalse, EFalse, 1);
1.218 + runTest(MemCopy, _L("Copy length cached"), EFalse, EFalse, EFalse, 1);
1.219 + runTest(MemCopyUncached, _L("Copy length uncached"), EFalse, EFalse, EFalse, 1);
1.220 + runTest(WordMove, _L("Word move length cached"), EFalse, EFalse, EFalse, 4);
1.221 + runTest(WordMoveUncached,_L("Word move length uncached"), EFalse, EFalse, EFalse, 4);
1.222 + break;
1.223 + default:
1.224 + test(EFalse);
1.225 + break;
1.226 + }
1.227 +
1.228 + test.End();
1.229 + return(KErrNone);
1.230 + }