summaryrefslogtreecommitdiff
path: root/src/mongo/dbtests/perftests.cpp
diff options
context:
space:
mode:
authorAndrew Morrow <acm@mongodb.com>2017-02-26 15:15:08 -0500
committerAndrew Morrow <acm@mongodb.com>2017-08-02 23:29:55 -0400
commita8a1ea3b9367adb6d0b65a7da21fed89598ea093 (patch)
tree8e969ed54b88c2a9c4c2d45a6518d053ac9f4265 /src/mongo/dbtests/perftests.cpp
parentc02c14e30d75b02894da116f4bb1a71652ead2b4 (diff)
downloadmongo-a8a1ea3b9367adb6d0b65a7da21fed89598ea093.tar.gz
SERVER-26538 SERVER-26539 Detach from boost::thread
Also, use thread_local everywhere for our thread specific data needs and remove the legacy support.
Diffstat (limited to 'src/mongo/dbtests/perftests.cpp')
-rw-r--r--src/mongo/dbtests/perftests.cpp468
1 files changed, 0 insertions, 468 deletions
diff --git a/src/mongo/dbtests/perftests.cpp b/src/mongo/dbtests/perftests.cpp
deleted file mode 100644
index 042b3629b5d..00000000000
--- a/src/mongo/dbtests/perftests.cpp
+++ /dev/null
@@ -1,468 +0,0 @@
-/**
- * Copyright (C) 2008 10gen Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the GNU Affero General Public License in all respects
- * for all of the code used other than as permitted herein. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you do not
- * wish to do so, delete this exception statement from your version. If you
- * delete this exception statement from all source files in the program,
- * then also delete it in the license file.
- */
-
-/** @file perftests.cpp.cpp : unit tests relating to performance
-
- The idea herein is tests that run fast and can be part of the normal CI suite. So no
- tests herein that take a long time to run. Obviously we need those too, but they will be
- separate.
-
- These tests use DBDirectClient; they are a bit white-boxish.
-*/
-
-#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault
-
-#include "mongo/platform/basic.h"
-
-#include <boost/thread/condition.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/thread.hpp>
-#include <iomanip>
-#include <iostream>
-#include <mutex>
-
-#include "mongo/config.h"
-#include "mongo/db/bson/dotted_path_support.h"
-#include "mongo/db/client.h"
-#include "mongo/db/db.h"
-#include "mongo/db/dbdirectclient.h"
-#include "mongo/db/lasterror.h"
-#include "mongo/db/storage/mmap_v1/dur_stats.h"
-#include "mongo/db/storage/mmap_v1/mmap.h"
-#include "mongo/db/storage/storage_options.h"
-#include "mongo/dbtests/dbtests.h"
-#include "mongo/dbtests/framework_options.h"
-#include "mongo/stdx/condition_variable.h"
-#include "mongo/stdx/thread.h"
-#include "mongo/util/log.h"
-#include "mongo/util/timer.h"
-#include "mongo/util/version.h"
-
-namespace PerfTests {
-
-using std::cout;
-using std::endl;
-using std::fixed;
-using std::left;
-using std::min;
-using std::right;
-using std::setprecision;
-using std::setw;
-using std::string;
-using std::vector;
-
-namespace dps = ::mongo::dotted_path_support;
-
-const bool profiling = false;
-
-class ClientBase {
-public:
- ClientBase() : _client(&_opCtx) {
- mongo::LastError::get(_opCtx.getClient()).reset();
- }
- virtual ~ClientBase() {
- mongo::LastError::get(_opCtx.getClient()).reset();
- }
-
-protected:
- void insert(const char* ns, BSONObj o) {
- _client.insert(ns, o);
- }
- void update(const char* ns, BSONObj q, BSONObj o, bool upsert = 0) {
- _client.update(ns, Query(q), o, upsert);
- }
- bool error() {
- return !_client.getPrevError().getField("err").isNull();
- }
-
- DBClientBase* client() {
- return &_client;
- }
- OperationContext* opCtx() {
- return &_opCtx;
- }
-
-private:
- const ServiceContext::UniqueOperationContext _txnPtr = cc().makeOperationContext();
- OperationContext& _opCtx = *_txnPtr;
- DBDirectClient _client;
-};
-
-static std::shared_ptr<DBClientConnection> conn;
-static string _perfhostname;
-
-class B : public ClientBase {
- string _ns;
-
-protected:
- const char* ns() {
- return _ns.c_str();
- }
-
- // anything you want to do before being timed
- virtual void prep() {}
-
- // anything you want to do before threaded test
- virtual void prepThreaded() {}
-
- virtual void timed() = 0;
-
- // optional 2nd test phase to be timed separately. You must provide it with a unique
- // name in order for it to run by overloading 'name2'.
- virtual void timed2(DBClientBase*) {}
-
- // return name of second test.
- virtual string name2() {
- return name();
- }
-
- virtual void post() {}
-
- virtual string name() = 0;
-
- // how long to run test. 0 is a sentinel which means just run the timed() method once and time
- // it.
- virtual int howLongMillis() {
- return profiling ? 30000 : 5000;
- }
-
- /* override if your test output doesn't need that */
- virtual bool showDurStats() {
- return true;
- }
-
-public:
- virtual unsigned batchSize() {
- return 50;
- }
-
- void say(unsigned long long n, long long us, string s) {
- unsigned long long rps = (n * 1000 * 1000) / (us > 0 ? us : 1);
- cout << "stats " << setw(42) << left << s << ' ' << right << setw(9) << rps << ' ' << right
- << setw(5) << us / 1000 << "ms ";
- if (showDurStats()) {
- cout << dur::stats.curr()->_asCSV();
- }
- cout << endl;
-
- if (conn && !conn->isFailed()) {
- const char* ns = "perf.pstats";
- if (frameworkGlobalParams.perfHist) {
- static bool needver = true;
- try {
- // try to report rps from last time */
- Query q;
- {
- BSONObjBuilder b;
- b.append("host", _perfhostname);
- b.append("test", s);
- b.append("dur", storageGlobalParams.dur);
- DEV {
- b.append("info.DEBUG", true);
- }
- else b.appendNull("info.DEBUG");
- if (sizeof(int*) == 4)
- b.append("info.bits", 32);
- else
- b.appendNull("info.bits");
- q = Query(b.obj()).sort("when", -1);
- }
- BSONObj fields = BSON("rps" << 1 << "info" << 1);
- vector<BSONObj> v;
- conn->findN(v, ns, q, frameworkGlobalParams.perfHist, 0, &fields);
- for (vector<BSONObj>::iterator i = v.begin(); i != v.end(); i++) {
- BSONObj o = *i;
- double lastrps = o["rps"].Number();
- if (0 && lastrps) {
- cout << "stats " << setw(42) << right << "new/old:" << ' ' << setw(9);
- cout << fixed << setprecision(2) << rps / lastrps;
- if (needver) {
- cout << " "
- << dps::extractElementAtPath(o, "info.git").toString();
- }
- cout << '\n';
- }
- }
- } catch (...) {
- }
- cout.flush();
- needver = false;
- }
- {
- bob b;
- b.append("host", _perfhostname);
- b.appendTimeT("when", time(0));
- b.append("test", s);
- b.append("rps", (int)rps);
- b.append("millis", us / 1000);
- b.appendBool("dur", storageGlobalParams.dur);
- if (showDurStats() && storageGlobalParams.dur) {
- b.append("durStats", dur::stats.asObj());
- }
-
- {
- auto&& vii = VersionInfoInterface::instance();
- bob inf;
- inf.append("version", vii.version());
- if (sizeof(int*) == 4)
- inf.append("bits", 32);
- DEV inf.append("DEBUG", true);
-#if defined(_WIN32)
- inf.append("os", "win");
-#endif
- inf.append("git", vii.gitVersion());
-#ifdef MONGO_CONFIG_SSL
- inf.append("OpenSSL", vii.openSSLVersion());
-#endif
- inf.append("boost", BOOST_VERSION);
- b.append("info", inf.obj());
- }
- BSONObj o = b.obj();
- // cout << "inserting " << o.toString() << endl;
- try {
- conn->insert(ns, o);
- } catch (std::exception& e) {
- warning() << "couldn't save perf results: " << e.what() << endl;
- }
- }
- }
- }
-
- /** if true runs timed2() again with several threads (8 at time of this writing).
- */
- virtual bool testThreaded() {
- return false;
- }
-
- int howLong() {
- int hlm = howLongMillis();
- DEV {
- // don't run very long with in debug mode - not very meaningful anyway on that build
- hlm = min(hlm, 500);
- }
- return hlm;
- }
-
- void run() {
- unsigned long long n = 0;
-
- _ns = string("perftest.") + name();
- client()->dropCollection(ns());
- prep();
- int hlm = howLong();
- mongo::Timer t;
- n = 0;
- const unsigned int Batch = batchSize();
-
- if (hlm == 0) {
- // means just do once
- timed();
- } else {
- do {
- unsigned int i;
- for (i = 0; i < Batch; i++)
- timed();
- n += i;
- } while (t.micros() < (hlm * 1000));
- }
-
- client()->getLastError(); // block until all ops are finished
-
- say(n, t.micros(), name());
-
- post();
-
- string test2name = name2();
- {
- if (test2name != name()) {
- dur::stats.curr()->reset();
- mongo::Timer t;
- unsigned long long n = 0;
- while (1) {
- unsigned int i;
- for (i = 0; i < Batch; i++)
- timed2(client());
- n += i;
- if (t.millis() > hlm)
- break;
- }
- say(n, t.micros(), test2name);
- }
- }
-
- if (testThreaded()) {
- const int nThreads = 8;
- // cout << "testThreaded nThreads:" << nThreads << endl;
- mongo::Timer t;
- const unsigned long long result = launchThreads(nThreads);
- say(result / nThreads, t.micros(), test2name + "-threaded");
- }
- }
-
- bool stop;
-
- void thread(unsigned long long* counter) {
-#if defined(_WIN32)
- static int z;
- srand(++z ^ (unsigned)time(0));
-#endif
- Client::initThreadIfNotAlready("perftestthr");
- const ServiceContext::UniqueOperationContext opCtxPtr = cc().makeOperationContext();
- OperationContext& opCtx = *opCtxPtr;
- DBDirectClient c(&opCtx);
-
- const unsigned int Batch = batchSize();
- prepThreaded();
- while (1) {
- unsigned int i = 0;
- for (i = 0; i < Batch; i++)
- timed2(&c);
- *counter += i;
- if (stop)
- break;
- }
- }
-
- unsigned long long launchThreads(int remaining) {
- stop = false;
- if (!remaining) {
- int hlm = howLong();
- sleepmillis(hlm);
- stop = true;
- return 0;
- }
- unsigned long long counter = 0;
- stdx::thread athread(stdx::bind(&B::thread, this, &counter));
- unsigned long long child = launchThreads(remaining - 1);
- athread.join();
- unsigned long long accum = child + counter;
- return accum;
- }
-};
-
-SimpleMutex m;
-boost::mutex mboost; // NOLINT
-boost::timed_mutex mboost_timed; // NOLINT
-std::mutex mstd; // NOLINT
-std::timed_mutex mstd_timed; // NOLINT
-SpinLock s;
-stdx::condition_variable c;
-
-class boostmutexspeed : public B {
-public:
- string name() {
- return "boost::mutex";
- }
- virtual int howLongMillis() {
- return 500;
- }
- virtual bool showDurStats() {
- return false;
- }
- void timed() {
- boost::lock_guard<boost::mutex> lk(mboost); // NOLINT
- }
-};
-class boosttimed_mutexspeed : public B {
-public:
- string name() {
- return "boost::timed_mutex";
- }
- virtual int howLongMillis() {
- return 500;
- }
- virtual bool showDurStats() {
- return false;
- }
- void timed() {
- boost::lock_guard<boost::timed_mutex> lk(mboost_timed); // NOLINT
- }
-};
-class simplemutexspeed : public B {
-public:
- string name() {
- return "simplemutex";
- }
- virtual int howLongMillis() {
- return 500;
- }
- virtual bool showDurStats() {
- return false;
- }
- void timed() {
- stdx::lock_guard<SimpleMutex> lk(m);
- }
-};
-
-class stdmutexspeed : public B {
-public:
- string name() {
- return "std::mutex";
- }
- virtual int howLongMillis() {
- return 500;
- }
- virtual bool showDurStats() {
- return false;
- }
- void timed() {
- std::lock_guard<std::mutex> lk(mstd); // NOLINT
- }
-};
-class stdtimed_mutexspeed : public B {
-public:
- string name() {
- return "std::timed_mutex";
- }
- virtual int howLongMillis() {
- return 500;
- }
- virtual bool showDurStats() {
- return false;
- }
- void timed() {
- std::lock_guard<std::timed_mutex> lk(mstd_timed); // NOLINT
- }
-};
-
-
-class All : public Suite {
-public:
- All() : Suite("perf") {}
-
- void setupTests() {
- cout << "stats test rps------ time-- "
- << dur::stats.curr()->_CSVHeader() << endl;
- add<simplemutexspeed>();
- add<boostmutexspeed>();
- add<boosttimed_mutexspeed>();
- add<stdmutexspeed>();
- add<stdtimed_mutexspeed>();
- }
-} myall;
-} // namespace PerfTests