Commit 7340a642 authored by David Auer's avatar David Auer
Browse files

Add benchmark function

parent 7accb100
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -35,4 +35,6 @@ extern "C" {
#define RPC_DATA                                                               \
    (static_cast<gkfs::daemon::RPCData*>(gkfs::daemon::RPCData::getInstance()))

int benchmark(std::string);

#endif // GKFS_DAEMON_DAEMON_HPP
+121 −0
Original line number Diff line number Diff line
@@ -566,6 +566,9 @@ main(int argc, const char* argv[]) {
        desc.add_options()(
                "start-relocation",
                "WIP: Send signal for relocation phase to all running daemons, then quit.");
        desc.add_options()(
                "benchmark", po::value<string>(),
                "WIP: Benchmark single code-paths. Supported values: rng, simplehash, randomslicing, randomslicing-agedconf");
    }
    desc.add_options()(
            "auto-sm",
@@ -580,6 +583,11 @@ main(int argc, const char* argv[]) {
        return 1;
    }

    if(vm.count("benchmark")) {
        cout << "Benchmark mode\n";
        return benchmark(vm["benchmark"].as<string>());
    }

    if(vm.count("version")) {
        cout << GKFS_VERSION_STRING << endl;
#ifndef NDEBUG
@@ -650,3 +658,116 @@ main(int argc, const char* argv[]) {
    GKFS_DATA->spdlogger()->info("{}() Complete. Exiting...", __func__);
    return 0;
}

// TODO(dauer) move this to it's own file

#include <chrono>

#include <random>
#include <string>
#include <global/rpc/distributor.hpp>

// create random string - nothing fancy, just some realistic input data for our
// hash algorithms Thanks to Galik from StackOverflow:
// https://stackoverflow.com/a/24586587
std::string
random_string(std::string::size_type length) {
    static auto& chrs = "0123456789"
                        "abcdefghijklmnopqrstuvwxyz"
                        "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    thread_local static std::mt19937 rg{std::random_device{}()};
    thread_local static std::uniform_int_distribution<std::string::size_type>
            pick(0, sizeof(chrs) - 2);

    std::string s;

    s.reserve(length);

    while(length--) s += chrs[pick(rg)];

    return s;
}


int
benchmark(string selector) {
    // TODO rng, simplehash, randomslicing, randomslicing-agedconf
    long rounds = 1e7;
    size_t hosts_size = 100; // TODO(daue) rs-conf fails with 1000 :/
    bool simplehash = false;
    bool randomslicing = false;
    bool agedconf = false;
    if(selector == "rng"s) {
        // all stay false
    } else if(selector == "simplehash"s) {
        simplehash = true;
    } else if(selector == "randomslicing"s) {
        randomslicing = true;
    } else if(selector == "randomslicing-agedconf"s) {
        randomslicing = true;
        agedconf = true;
    } else {
        cout << "Wrong argument: " << selector << "\n";
        return 1;
    }

    cout << "Starting " << rounds << " rounds of " << selector << "\n";

    // init stuff (always both RS and simplehash)

    auto distributor = std::shared_ptr<gkfs::rpc::Distributor>(
            new gkfs::rpc::SimpleHashDistributor(0, hosts_size));

    // mock up a random slicing distribution with hosts_size hosts
    auto rs_dist = std::make_shared<VDRIVE::DistRandSlice>();
    list<VDRIVE::Disk*> disks;
    for(size_t i = 0; i < hosts_size; i++) {
        disks.emplace_back(new VDRIVE::Disk(i, 1, "hostname", "uri"));
    }
    rs_dist->addDisks(&disks);


    if(agedconf) {
        // do some iterations of add/remove with rs_dist
    }

    if(randomslicing) {
        distributor = std::shared_ptr<gkfs::rpc::Distributor>(
                new gkfs::rpc::RandomSlicingDistributor(rs_dist));
    }


    // start timer
    auto t1 = std::chrono::steady_clock::now();


    for(long i = 0; i < rounds; i++) {
        auto mock_path = random_string(10);
        if(simplehash || randomslicing) {
            distributor->locate_data(mock_path, i); // more specific stuff?
            distributor->locate_file_metadata(mock_path);
        }

        if(i % (rounds / 10) == 0) {
            cout << i << " rounds done...\n";
        }
    }


    auto t2 = std::chrono::steady_clock::now();
    auto duration_ms =
            std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1)
                    .count();

    cout << "Done " << rounds << " rounds of " << selector << " in "
         << duration_ms << "ms, that's " << (rounds * 1000 / duration_ms)
         << " operations/s or " << ((double) rounds / 1000 / duration_ms)
         << " mega-ops/s\n";
    cout << "Note: Each operation consists of one locate_data and one locate_file_metadata call.\n";
    cout << "Simulation run with " << hosts_size << " hosts.\n";
    // TODO(dauer) Print RS-Conf information


    return 0;
}
 No newline at end of file