|
reSIProcate/rutil
9694
|
#include <cstdlib>#include <cmath>#include <iostream>#include <vector>#include <memory>#include <set>#include "rutil/Random.hxx"#include "rutil/Time.hxx"#include "rutil/Lock.hxx"
Go to the source code of this file.
Classes | |
| class | Barrier |
| class | TestDummyThread |
| class | TestRandomThread |
Defines | |
| #define | RANDINT_PER_CYCLE (1000000) |
| Helper to test the speed of of the random generator. | |
| #define | RANDSEQ_PER_CYCLE (1000) |
Typedefs | |
| typedef std::set< Data > | DataSet |
Functions | |
| static UInt64 | doSingleTest (int numCycles) |
| static int | mergeCheckRandoms (DataSet &all, const DataSet &more) |
| static UInt64 | doThreadedTest (int numCycles, int numThreads, int storeBytes) |
| static void | doVariationTest (int numCycles, int numThreads, int numPass, int storeBytes) |
| int | main (int argc, char **argv) |
| #define RANDINT_PER_CYCLE (1000000) |
Helper to test the speed of of the random generator.
Used to optimize the different flavors.
Definition at line 18 of file testRandomThread.cxx.
Referenced by TestRandomThread::makeRandoms().
| #define RANDSEQ_PER_CYCLE (1000) |
Definition at line 19 of file testRandomThread.cxx.
Referenced by TestRandomThread::makeAndStoreRandoms().
Definition at line 80 of file testRandomThread.cxx.
| static UInt64 doSingleTest | ( | int | numCycles | ) | [static] |
Definition at line 162 of file testRandomThread.cxx.
References TestRandomThread::makeRandoms().
Referenced by doVariationTest().
{
UInt64 startUs = ResipClock::getTimeMicroSec();
TestRandomThread::makeRandoms(numCycles);
UInt64 doneUs = ResipClock::getTimeMicroSec();
return doneUs - startUs;
}

| static UInt64 doThreadedTest | ( | int | numCycles, |
| int | numThreads, | ||
| int | storeBytes | ||
| ) | [static] |
Definition at line 193 of file testRandomThread.cxx.
References TestRandomThread::getDupCnt(), TestRandomThread::getRandoms(), resip::ThreadIf::join(), mergeCheckRandoms(), resip::ThreadIf::run(), and Barrier::sync().
Referenced by doVariationTest().
{
std::vector<TestRandomThread*> threadList;
Barrier bar(numThreads);
int pidx;
for (pidx=0; pidx < numThreads; pidx++)
{
TestRandomThread* rth = new TestRandomThread(numCycles,bar, storeBytes);
rth->run();
threadList.push_back(rth);
}
// std::cerr << "Threads started." << std::endl;
bar.sync(1, true);
UInt64 startUs = ResipClock::getTimeMicroSec();
// TestRandomThread::makeRandoms(numCycles);
bar.sync(2, true);
UInt64 doneUs = ResipClock::getTimeMicroSec();
// std::cerr << "Threads finished."
// << " (barrier pre="<<Barrier::sPreWaitCnt
// << " post="<<Barrier::sPostWaitCnt
// <<")" << std::endl;
DataSet allRandoms;
int intraDupCnt = 0;
int interDupCnt = 0;
for (pidx=0; pidx < numThreads; pidx++)
{
TestRandomThread* rth = threadList[pidx];
if ( storeBytes > 0 )
{
intraDupCnt += rth->getDupCnt();
interDupCnt += mergeCheckRandoms(allRandoms, rth->getRandoms());
}
rth->join();
delete rth;
}
if ( storeBytes > 0 )
{
std::cout << "Found "<<interDupCnt<< " inter-thread and "
<<intraDupCnt<<" intra-thread duplicates." << std::endl;
}
return doneUs - startUs;
}

| static void doVariationTest | ( | int | numCycles, |
| int | numThreads, | ||
| int | numPass, | ||
| int | storeBytes | ||
| ) | [static] |
Definition at line 243 of file testRandomThread.cxx.
References doSingleTest(), and doThreadedTest().
Referenced by main().
{
UInt64 msMin = 0, msMax = 0;
UInt64 msSum = 0;
UInt64 msSumSq = 0;
int passIdx=0;
for (passIdx=0; passIdx < numPass; passIdx++)
{
UInt64 usTot = numThreads<=0
? doSingleTest(numCycles)
: doThreadedTest(numCycles, numThreads, storeBytes);
UInt64 usPerCycle = usTot/numCycles;
#if 0
std::cerr << numCycles << " cycles/thread (1M plain 32-bit ints)"
<< " with " << numThreads << " threads"
<< " took " << usTot<<"us (" << usPerCycle << "us/cycle)"
<< std::endl;
#endif
UInt64 msPerCycle = usPerCycle/1000;
msSum += msPerCycle;
msSumSq += msPerCycle*msPerCycle;
if ( msPerCycle < msMin || passIdx==0 )
msMin = msPerCycle;
if ( msPerCycle > msMax || passIdx==0 )
msMax = msPerCycle;
}
double msAvg = msSum/(numPass+0.0);
double msVar = msSumSq/(numPass+0.0) - msAvg*msAvg;
double msStd = sqrt(msVar);
double msStdPct = msStd/msAvg*100;
fprintf(stderr,"RESULT:plain:%s:cycles=%d,threads=%d,passes=%d:min=%d,avg=%d,max=%d,std=%.1f(%.1f%%)[ms/cycle]\n",
Random::getImplName(),
numCycles, numThreads, numPass,
(int)msMin,(int)msAvg,(int)msMax, msStd, msStdPct);
}

| int main | ( | int | argc, |
| char ** | argv | ||
| ) |
Definition at line 280 of file testRandomThread.cxx.
References doVariationTest().
{
bool doSweep = true;
int numCycles = 2;
int numThreads = 3;
int numPass = 10;
int storeBytes = 0;
{
doSweep = false;
if(argc >= 2)
numCycles = atoi(argv[1]);
if(argc >= 3)
numThreads = atoi(argv[2]);
if(argc >= 4)
numPass = atoi(argv[3]);
if(argc >= 5)
storeBytes = atoi(argv[4]);
}
if (numCycles <= 0 || numThreads < -1 || numPass < 1)
{
std::cerr
<< "usage: testRandomThread [numCycles numThreads numPasses storeBytes]" << std::endl
<< "numCycles>0 is number of cycles to run in each thread." << std::endl
<< " each cycle is one million random 32bit integers" << std::endl
<< " each cycle is one thousand random sequences when storing (see below) " << std::endl
<< "numThreads>=-1 is number of threads to run " << std::endl
<< " -1 ==> work in main thread only" << std::endl
<< " 0 ==> work in main thread, plus dummy thread doing nothing" << std::endl
<< " 1 ==> single working thread, plus dummy & main doing nothing" << std::endl
<< " N ==> this many working threads, plus dummy & main doing nothing" << std::endl
<< "numPasses>=1 is number of time to repeat test (for min/max/stdev) " << std::endl
<< "Reported metric (min/avg/max/stdev) are milliseconds per cycle for all threads to complete." << std::endl
<< "storeBytes>=0 will store random sequences of this many bytes" << std::endl
<< " and check for duplicates. Mainly to check for thread safety." << std::endl
<< " Timing numbers in this case are not so useful." << std::endl
<< " 0 ==> [default] Don't store, just time." << std::endl
;
exit(-1);
}
std::auto_ptr<TestDummyThread> dummyThread;
if ( numThreads >= 0 )
{
dummyThread.reset(new TestDummyThread);
dummyThread->run();
}
std::cerr << "Starting..." << std::endl;
{
doVariationTest(numCycles, numThreads, numPass, storeBytes);
}
std::cerr << "Success." << std::endl;
return 0;
}

Definition at line 171 of file testRandomThread.cxx.
Referenced by doThreadedTest().
{
int dupCnt = 0;
DataSet::const_iterator it = more.begin();
// DataSet::iterator at = all.begin();
for ( ; it != more.end(); ++it)
{
// STL is unbelieable: this form isn't supported:
// std::pair<DataSet::iterator,bool> res = all.insert( at, *it);
// So we have to do this NlgN style:
std::pair<DataSet::iterator,bool> res = all.insert( *it);
// at = res->first;
if ( res.second == false )
{
++dupCnt;
// std::cerr << "Inter-thread duplicate found." << std::endl;
}
}
return dupCnt;
}
1.7.5.1