diff options
Diffstat (limited to 'src/mongo/client/examples/mongoperf.cpp')
-rw-r--r-- | src/mongo/client/examples/mongoperf.cpp | 189 |
1 files changed, 97 insertions, 92 deletions
diff --git a/src/mongo/client/examples/mongoperf.cpp b/src/mongo/client/examples/mongoperf.cpp index 88d3d03e422..1681e8a9113 100644 --- a/src/mongo/client/examples/mongoperf.cpp +++ b/src/mongo/client/examples/mongoperf.cpp @@ -61,11 +61,11 @@ using namespace mongoutils::str; int dummy; unsigned recSizeKB; -LogFile *lf = 0; -MemoryMappedFile *mmfFile; -char *mmf = 0; +LogFile* lf = 0; +MemoryMappedFile* mmfFile; +char* mmf = 0; bo options; -unsigned long long len; // file len +unsigned long long len; // file len const unsigned PG = 4096; unsigned nThreadsRunning = 0; @@ -77,22 +77,23 @@ SimpleMutex m; int syncDelaySecs = 0; void syncThread() { - while( 1 ) { + while (1) { mongo::Timer t; mmfFile->flush(true); - cout << " mmf sync took " << t.millis() << "ms" << endl; + cout << " mmf sync took " << t.millis() + << "ms" << endl; sleepsecs(syncDelaySecs); } } -void stripTrailing(std::string& s, const char *chars) { +void stripTrailing(std::string& s, const char* chars) { std::string::iterator to = s.begin(); - for ( std::string::iterator i = s.begin(); i != s.end(); i++ ) { + for (std::string::iterator i = s.begin(); i != s.end(); i++) { // During each iteration if i finds a non-"chars" character it writes it to the // position of t. So the part of the string left from the "to" iterator is already // "cleared" string. - if ( !contains(chars, *i) ) { - if ( i != to ) + if (!contains(chars, *i)) { + if (i != to) s.replace(to, to + 1, 1, *i); to++; } @@ -101,14 +102,16 @@ void stripTrailing(std::string& s, const char *chars) { } char* round(char* x) { - size_t f = (size_t) x; - char *p = (char *) ((f+PG-1)/PG*PG); + size_t f = (size_t)x; + char* p = (char*)((f + PG - 1) / PG * PG); return p; } struct Aligned { char x[8192]; - char* addr() { return round(x); } + char* addr() { + return round(x); + } }; unsigned long long rrand() { @@ -122,118 +125,118 @@ void workerThread() { cout << "read:" << r << " write:" << w << endl; long long su = options["sleepMicros"].numberLong(); Aligned a; - while( 1 ) { + while (1) { unsigned long long rofs = (rrand() * PG) % len; unsigned long long wofs = (rrand() * PG) % len; - const unsigned P = PG/1024; - if( mmf ) { - if( r ) { - for( unsigned p = P; p <= recSizeKB; p += P ) { - if( rofs < len ) + const unsigned P = PG / 1024; + if (mmf) { + if (r) { + for (unsigned p = P; p <= recSizeKB; p += P) { + if (rofs < len) dummy += mmf[rofs]; rofs += PG; } iops.fetchAndAdd(1); } - if( w ) { - for( unsigned p = P; p <= recSizeKB; p += P ) { - if( wofs < len ) + if (w) { + for (unsigned p = P; p <= recSizeKB; p += P) { + if (wofs < len) mmf[wofs] = 3; wofs += PG; } iops.fetchAndAdd(1); } - } - else { - if( r ) { + } else { + if (r) { lf->readAt(rofs, a.addr(), recSizeKB * 1024); iops.fetchAndAdd(1); } - if( w ) { + if (w) { lf->writeAt(wofs, a.addr(), recSizeKB * 1024); iops.fetchAndAdd(1); } } long long micros = su / nThreadsRunning; - if( micros ) { + if (micros) { sleepmicros(micros); } } } void go() { - verify( options["r"].trueValue() || options["w"].trueValue() ); + verify(options["r"].trueValue() || options["w"].trueValue()); recSizeKB = options["recSizeKB"].numberInt(); - if( recSizeKB == 0 ) + if (recSizeKB == 0) recSizeKB = 4; - verify( recSizeKB <= 64000 && recSizeKB > 0 ); + verify(recSizeKB <= 64000 && recSizeKB > 0); MemoryMappedFile f; cout << "creating test file size:"; len = options["fileSizeMB"].numberLong(); - if( len == 0 ) len = 1; + if (len == 0) + len = 1; cout << len << "MB ..." << endl; - if( 0 && len > 2000 && !options["mmf"].trueValue() ) { + if (0 && len > 2000 && !options["mmf"].trueValue()) { // todo make tests use 64 bit offsets in their i/o -- i.e. adjust LogFile::writeAt and such cout << "\nsizes > 2GB not yet supported with mmf:false" << endl; return; } len *= 1024 * 1024; - const char *fname = "./mongoperf__testfile__tmp"; + const char* fname = "./mongoperf__testfile__tmp"; try { boost::filesystem::remove(fname); - } - catch(...) { + } catch (...) { cout << "error deleting file " << fname << endl; return; } - lf = new LogFile(fname,true); - const unsigned sz = 1024 * 1024 * 32; // needs to be big as we are using synchronousAppend. if we used a regular MongoFile it wouldn't have to be - char *buf = (char*) mongoMalloc(sz+4096); - const char *p = round(buf); - for( unsigned long long i = 0; i < len; i += sz ) { + lf = new LogFile(fname, true); + const unsigned sz = 1024 * 1024 * + 32; // needs to be big as we are using synchronousAppend. if we used a regular MongoFile it wouldn't have to be + char* buf = (char*)mongoMalloc(sz + 4096); + const char* p = round(buf); + for (unsigned long long i = 0; i < len; i += sz) { lf->synchronousAppend(p, sz); - if( i % (1024ULL*1024*1024) == 0 && i ) { - cout << i / (1024ULL*1024*1024) << "GB..." << endl; + if (i % (1024ULL * 1024 * 1024) == 0 && i) { + cout << i / (1024ULL * 1024 * 1024) << "GB..." << endl; } } BSONObj& o = options; - if( o["mmf"].trueValue() ) { + if (o["mmf"].trueValue()) { delete lf; lf = 0; mmfFile = new MemoryMappedFile(); - mmf = (char *) mmfFile->map(fname); - verify( mmf ); + mmf = (char*)mmfFile->map(fname); + verify(mmf); syncDelaySecs = options["syncDelay"].numberInt(); - if( syncDelaySecs ) { + if (syncDelaySecs) { stdx::thread t(syncThread); } } - cout << "testing..."<< endl; + cout << "testing..." << endl; cout << "options:" << o.toString() << endl; unsigned wthr = 1; - if( !o["nThreads"].eoo() ) { - wthr = (unsigned) o["nThreads"].Int(); + if (!o["nThreads"].eoo()) { + wthr = (unsigned)o["nThreads"].Int(); } cout << "wthr " << wthr << endl; - if( wthr < 1 ) { + if (wthr < 1) { cout << "bad threads field value" << endl; return; } unsigned i = 0; unsigned d = 1; - unsigned &nthr = nThreadsRunning; - while( 1 ) { - if( i++ % 8 == 0 ) { - if( nthr < wthr ) { - while( nthr < wthr && nthr < d ) { + unsigned& nthr = nThreadsRunning; + while (1) { + if (i++ % 8 == 0) { + if (nthr < wthr) { + while (nthr < wthr && nthr < d) { nthr++; stdx::thread w(workerThread); } @@ -244,48 +247,52 @@ void go() { sleepsecs(1); unsigned long long w = iops.loadRelaxed(); iops.store(0); - w /= 1; // 1 secs + w /= 1; // 1 secs cout << w << " ops/sec "; - if( mmf == 0 ) + if (mmf == 0) // only writing 4 bytes with mmf so we don't say this cout << (w * PG / 1024 / 1024) << " MB/sec"; cout << endl; } } -int main(int argc, char *argv[]) { - +int main(int argc, char* argv[]) { try { cout << "mongoperf" << endl; - if( argc > 1 ) { -cout << - -"\n" -"usage:\n" -"\n" -" mongoperf < myjsonconfigfile\n" -"\n" -" {\n" -" nThreads:<n>, // number of threads (default 1)\n" -" fileSizeMB:<n>, // test file size (default 1MB)\n" -" sleepMicros:<n>, // pause for sleepMicros/nThreads between each operation (default 0)\n" -" mmf:<bool>, // if true do i/o's via memory mapped files (default false)\n" -" r:<bool>, // do reads (default false)\n" -" w:<bool>, // do writes (default false)\n" -" recSizeKB:<n>, // size of each write (default 4KB)\n" -" syncDelay:<n> // secs between fsyncs, like --syncdelay in mongod. (default 0/never)\n" -" }\n" -"\n" -"mongoperf is a performance testing tool. the initial tests are of disk subsystem performance; \n" -" tests of mongos and mongod will be added later.\n" -"most fields are optional.\n" -"non-mmf io is direct io (no caching). use a large file size to test making the heads\n" -" move significantly and to avoid i/o coalescing\n" -"mmf io uses caching (the file system cache).\n" -"\n" - -<< endl; + if (argc > 1) { + cout << + + "\n" + "usage:\n" + "\n" + " mongoperf < myjsonconfigfile\n" + "\n" + " {\n" + " nThreads:<n>, // number of threads (default 1)\n" + " fileSizeMB:<n>, // test file size (default 1MB)\n" + " sleepMicros:<n>, // pause for sleepMicros/nThreads between each operation " + "(default 0)\n" + " mmf:<bool>, // if true do i/o's via memory mapped files (default " + "false)\n" + " r:<bool>, // do reads (default false)\n" + " w:<bool>, // do writes (default false)\n" + " recSizeKB:<n>, // size of each write (default 4KB)\n" + " syncDelay:<n> // secs between fsyncs, like --syncdelay in mongod. " + "(default 0/never)\n" + " }\n" + "\n" + "mongoperf is a performance testing tool. the initial tests are of disk subsystem " + "performance; \n" + " tests of mongos and mongod will be added later.\n" + "most fields are optional.\n" + "non-mmf io is direct io (no caching). use a large file size to test making the " + "heads\n" + " move significantly and to avoid i/o coalescing\n" + "mmf io uses caching (the file system cache).\n" + "\n" + + << endl; return EXIT_SUCCESS; } @@ -294,7 +301,7 @@ cout << char input[1024]; memset(input, 0, sizeof(input)); cin.read(input, 1000); - if( *input == 0 ) { + if (*input == 0) { cout << "error no options found on stdin for mongoperf" << endl; return EXIT_FAILURE; } @@ -303,8 +310,7 @@ cout << stripTrailing(s, " \n\r\0x1a"); try { options = fromjson(s); - } - catch(...) { + } catch (...) { cout << "couldn't parse json options. input was:\n|" << s << "|" << endl; return EXIT_FAILURE; } @@ -312,8 +318,7 @@ cout << ProcessInfo::initializeSystemInfo(); go(); - } - catch(DBException& e) { + } catch (DBException& e) { cout << "caught DBException " << e.toString() << endl; return EXIT_FAILURE; } |