From 109ed973e7da723337bd58e692b5987ae040f041 Mon Sep 17 00:00:00 2001 From: Greg Farnum Date: Tue, 9 Jun 2009 17:01:37 -0700 Subject: [PATCH] radostool now includes benchmarking functionality from testradosciopp.cc --- src/radostool.cc | 155 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 1 deletion(-) diff --git a/src/radostool.cc b/src/radostool.cc index 72eaaf12bbaa1..aa4a9d3f562eb 100644 --- a/src/radostool.cc +++ b/src/radostool.cc @@ -20,6 +20,11 @@ #include #include +#include + + +int aio_bench(Rados& rados, rados_pool_t pool, int concurrentios, int secondsToRun, + int writeSize, int readOffResults); void usage() { @@ -146,7 +151,17 @@ int main(int argc, const char **argv) exit(0); } - } else { + } else if (strcmp(nargs[0], "bench") == 0) { + if ( nargs.size() < 5) { + cerr << "bench requires 4 arguments: Concurrent writes," << std::endl + << "minimum seconds to run, write size, and consistency checking" << std::endl + << "(1 for yes, 0 for no)." << std::endl; + } + else { + aio_bench(rados, p, atoi(nargs[1]), atoi(nargs[2]), atoi(nargs[3]), atoi(nargs[4])); + } + } + else { cerr << "unrecognized command " << nargs[0] << std::endl; usage(); } @@ -172,3 +187,141 @@ int main(int argc, const char **argv) rados_deinitialize(); return 0; } + +/********************************************** + +**********************************************/ + +int aio_bench (Rados& rados, rados_pool_t pool, int concurrentios, int secondsToRun, + int writeSize, int readOffResults) { + + cout << "Maintaining " << concurrentios << " concurrent writes of " << writeSize + << " bytes for at least " << secondsToRun << " seconds.\n"; + + Rados::AioCompletion* completions[concurrentios]; + char* name[concurrentios]; + bufferlist* contents[concurrentios]; + char contentsChars[writeSize]; + double totalLatency = 0; + utime_t maxLatency; + utime_t startTimes[concurrentios]; + int writesMade = 0; + int writesCompleted = 0; + time_t initialTime; + utime_t startTime; + utime_t stopTime; + + time(&initialTime); + stringstream initialTimeS(""); + initialTimeS << initialTime; + const char* iTime = initialTimeS.str().c_str(); + maxLatency.set_from_double(0); + //set up writes so I can start them together + for (int i = 0; iappend(contentsChars, writeSize); + } + + //set up the pool, get start time, and go! + cout << "open pool result = " << rados.open_pool("data",&pool) << " pool = " << pool << std::endl; + + startTime = g_clock.now(); + + for (int i = 0; iappend(contentsChars, writeSize); + completions[slot]->wait_for_complete(); + currentLatency = g_clock.now() - startTimes[slot]; + totalLatency += currentLatency; + if( currentLatency > maxLatency) maxLatency = currentLatency; + ++writesCompleted; + completions[slot]->release(); + //write new stuff to rados, then delete old stuff + //and save locations of new stuff for later deletion + startTimes[slot] = g_clock.now(); + rados.aio_write(pool, newName, 0, *newContents, writeSize, &completions[slot]); + ++writesMade; + delete name[slot]; + delete contents[slot]; + name[slot] = newName; + contents[slot] = newContents; + } + + cerr << "Waiting for last writes to finish\n"; + while (writesCompleted < writesMade) { + slot = writesCompleted % concurrentios; + completions[slot]->wait_for_complete(); + currentLatency = g_clock.now() - startTimes[slot]; + totalLatency += currentLatency; + if (currentLatency > maxLatency) maxLatency = currentLatency; + completions[slot]-> release(); + ++writesCompleted; + delete name[slot]; + delete contents[slot]; + } + + utime_t timePassed = g_clock.now() - startTime; + + //check objects for consistency if requested + int errors = 0; + if (readOffResults) { + char matchName[128]; + object_t oid; + bufferlist actualContents; + for (int i = 0; i < writesCompleted; ++i ) { + snprintf(matchName, 128, "Object %s:%d", iTime, i); + oid = object_t(matchName); + snprintf(contentsChars, writeSize, "I'm the %dth object!", i); + rados.read(pool, oid, 0, actualContents, writeSize); + if (strcmp(contentsChars, actualContents.c_str()) != 0 ) { + cerr << "Object " << matchName << " is not correct!"; + ++errors; + } + actualContents.clear(); + } + } + + char bw[20]; + double bandwidth = ((double)writesCompleted)*((double)writeSize)/(double)timePassed; + bandwidth = bandwidth/(1024*1024); // we want it in MB/sec + sprintf(bw, "%.3lf \n", bandwidth); + + double averageLatency = totalLatency / writesCompleted; + + cout << "Total time run: " << timePassed << std::endl + << "Total writes made: " << writesCompleted << std::endl + << "Write size: " << writeSize << std::endl + << "Bandwidth (MB/sec): " << bw << std::endl + << "Average Latency: " << averageLatency << std::endl + << "Max latency: " << maxLatency << std::endl + << "Time waiting for Rados:" << totalLatency/concurrentios << std::endl; + + if (readOffResults) { + if (errors) cout << "WARNING: There were " << errors << " total errors in copying!\n"; + else cout << "No errors in copying!\n"; + } + return 0; +} -- 2.39.5