// ----------------------------------------------------------------------
// File: BM_FlatScheduler.cc
// Author: Abhishek Lekshmanan - CERN
// ----------------------------------------------------------------------
/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2023 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#include "benchmark/benchmark.h"
#include "common/utils/ContainerUtils.hh"
#include "mgm/placement/PlacementStrategy.hh"
#include "mgm/placement/ClusterMap.hh"
#include "mgm/placement/FlatScheduler.hh"
static void BM_Scheduler(benchmark::State& state) {
using namespace eos::mgm::placement;
auto n_groups = state.range(0);
auto n_elements = n_groups + 101;
const int n_disks_per_group = 16;
ClusterMgr mgr;
{
auto sh = mgr.getStorageHandler(n_elements);
sh.addBucket(get_bucket_type(StdBucketType::ROOT), 0);
sh.addBucket(get_bucket_type(StdBucketType::SITE), -1, 0);
for (int i=0; i< n_groups; ++i) {
sh.addBucket(get_bucket_type(StdBucketType::GROUP), -100-i, -1);
}
for (int i=0; i < n_groups*n_disks_per_group; i++) {
sh.addDisk(Disk(i+1, ConfigStatus::kRW, ActiveStatus::kOnline, 1),
-100 - i/n_disks_per_group);
}
}
FlatScheduler flat_scheduler(PlacementStrategyT::kRoundRobin, n_elements);
for (auto _: state) {
auto cluster_data_ptr = mgr.getClusterData();
benchmark::DoNotOptimize(flat_scheduler.schedule(cluster_data_ptr(),state.range(1)));
}
state.counters["frequency"] = benchmark::Counter(state.iterations(),
benchmark::Counter::kIsRate);
}
static void BM_ThreadLocalRRScheduler(benchmark::State& state) {
using namespace eos::mgm::placement;
auto n_groups = state.range(0);
auto n_elements = 1024;
const int n_disks_per_group = 16;
ClusterMgr mgr;
{
auto sh = mgr.getStorageHandler(n_elements);
sh.addBucket(get_bucket_type(StdBucketType::ROOT), 0);
//sh.addBucket(get_bucket_type(StdBucketType::SITE), -1, 0);
for (int i=0; i< n_groups; ++i) {
sh.addBucket(get_bucket_type(StdBucketType::GROUP), -100-i, 0);
}
for (int i=0; i < n_groups*n_disks_per_group; i++) {
sh.addDisk(Disk(i+1, ConfigStatus::kRW, ActiveStatus::kOnline, 1),
-100 - i/n_disks_per_group);
}
}
FlatScheduler flat_scheduler(PlacementStrategyT::kThreadLocalRoundRobin, n_elements);
for (auto _: state) {
auto cluster_data_ptr = mgr.getClusterData();
benchmark::DoNotOptimize(flat_scheduler.schedule(cluster_data_ptr(),state.range(1)));
}
state.counters["frequency"] = benchmark::Counter(state.iterations(),
benchmark::Counter::kIsRate);
}
static void BM_RandomScheduler(benchmark::State& state) {
using namespace eos::mgm::placement;
auto n_groups = state.range(0);
auto n_elements = 1024;
const int n_disks_per_group = 16;
ClusterMgr mgr;
{
auto sh = mgr.getStorageHandler(n_elements);
sh.addBucket(get_bucket_type(StdBucketType::ROOT), 0);
//sh.addBucket(get_bucket_type(StdBucketType::SITE), -1, 0);
for (int i=0; i< n_groups; ++i) {
sh.addBucket(get_bucket_type(StdBucketType::GROUP), -100-i, 0);
}
for (int i=0; i < n_groups*n_disks_per_group; i++) {
sh.addDisk(Disk(i+1, ConfigStatus::kRW, ActiveStatus::kOnline, 1),
-100 - i/n_disks_per_group);
}
}
FlatScheduler flat_scheduler(PlacementStrategyT::kRandom, n_elements);
for (auto _: state) {
auto cluster_data_ptr = mgr.getClusterData();
benchmark::DoNotOptimize(flat_scheduler.schedule(cluster_data_ptr(),state.range(1)));
}
state.counters["frequency"] = benchmark::Counter(state.iterations(),
benchmark::Counter::kIsRate);
}
static void BM_FidScheduler(benchmark::State& state) {
using namespace eos::mgm::placement;
auto n_groups = state.range(0);
auto n_elements = 1024;
const int n_disks_per_group = 16;
ClusterMgr mgr;
{
auto sh = mgr.getStorageHandler(n_elements);
sh.addBucket(get_bucket_type(StdBucketType::ROOT), 0);
//sh.addBucket(get_bucket_type(StdBucketType::SITE), -1, 0);
for (int i=0; i< n_groups; ++i) {
sh.addBucket(get_bucket_type(StdBucketType::GROUP), -100-i, 0);
}
for (int i=0; i < n_groups*n_disks_per_group; i++) {
sh.addDisk(Disk(i+1, ConfigStatus::kRW, ActiveStatus::kOnline, 1),
-100 - i/n_disks_per_group);
}
}
FlatScheduler flat_scheduler(PlacementStrategyT::kFidRandom, n_elements);
PlacementArguments args(state.range(1));
args.fid=1;
for (auto _: state) {
auto cluster_data_ptr = mgr.getClusterData();
benchmark::DoNotOptimize(flat_scheduler.schedule(cluster_data_ptr(), args));
args.fid++;
}
state.counters["frequency"] = benchmark::Counter(state.iterations(),
benchmark::Counter::kIsRate);
}
static void BM_WeightedRandomScheduler(benchmark::State& state) {
using namespace eos::mgm::placement;
auto n_groups = state.range(0);
auto n_elements = 1024;
const int n_disks_per_group = 16;
std::vector weights = {4,8,16};
ClusterMgr mgr;
{
auto sh = mgr.getStorageHandler(n_elements);
sh.addBucket(get_bucket_type(StdBucketType::ROOT), 0);
//sh.addBucket(get_bucket_type(StdBucketType::SITE), -1, 0);
for (int i=0; i< n_groups; ++i) {
sh.addBucket(get_bucket_type(StdBucketType::GROUP), -100-i, 0);
}
for (int i=0; i < n_groups*n_disks_per_group; i++) {
sh.addDisk(Disk(i+1, ConfigStatus::kRW, ActiveStatus::kOnline,
eos::common::pickIndexRR(weights, i)),
-100 - i/n_disks_per_group);
}
}
FlatScheduler flat_scheduler(PlacementStrategyT::kWeightedRandom, n_elements);
PlacementArguments args(state.range(1));
args.fid=1;
for (auto _: state) {
auto cluster_data_ptr = mgr.getClusterData();
benchmark::DoNotOptimize(flat_scheduler.schedule(cluster_data_ptr(), args));
args.fid++;
}
state.counters["frequency"] = benchmark::Counter(state.iterations(),
benchmark::Counter::kIsRate);
}
static void BM_WeightedRRScheduler(benchmark::State& state) {
using namespace eos::mgm::placement;
auto n_groups = state.range(0);
auto n_elements = 1024;
const int n_disks_per_group = 16;
std::vector weights = {4,8,16};
ClusterMgr mgr;
{
auto sh = mgr.getStorageHandler(n_elements);
sh.addBucket(get_bucket_type(StdBucketType::ROOT), 0);
//sh.addBucket(get_bucket_type(StdBucketType::SITE), -1, 0);
for (int i=0; i< n_groups; ++i) {
sh.addBucket(get_bucket_type(StdBucketType::GROUP), -100-i, 0);
}
for (int i=0; i < n_groups*n_disks_per_group; i++) {
sh.addDisk(Disk(i+1, ConfigStatus::kRW, ActiveStatus::kOnline,
eos::common::pickIndexRR(weights, i)),
-100 - i/n_disks_per_group);
}
}
FlatScheduler flat_scheduler(PlacementStrategyT::kWeightedRoundRobin, n_elements);
PlacementArguments args(state.range(1));
args.fid=1;
for (auto _: state) {
auto cluster_data_ptr = mgr.getClusterData();
benchmark::DoNotOptimize(flat_scheduler.schedule(cluster_data_ptr(), args));
args.fid++;
}
state.counters["frequency"] = benchmark::Counter(state.iterations(),
benchmark::Counter::kIsRate);
}
BENCHMARK(BM_Scheduler)->Threads(1)->Threads(8)->Threads(64)->Threads(128)->Threads(256)
->ArgsProduct({{32, 64, 128, 256, 512},
{2,3,6}})->UseRealTime();
BENCHMARK(BM_ThreadLocalRRScheduler)->Threads(1)->Threads(8)->Threads(64)->Threads(128)->Threads(256)
->ArgsProduct({{32, 64, 128, 256, 512},
{2,3,6}})->UseRealTime();
BENCHMARK(BM_RandomScheduler)->Threads(1)->Threads(8)->Threads(64)->Threads(128)->Threads(256)
->ArgsProduct({{32, 64, 128, 256, 512},
{2,3,6}})->UseRealTime();
BENCHMARK(BM_FidScheduler)->Threads(1)->Threads(8)->Threads(64)->Threads(128)->Threads(256)
->ArgsProduct({{32, 64, 128, 256, 512},
{2,3,6}})->UseRealTime();
BENCHMARK(BM_WeightedRandomScheduler)->Threads(1)->Threads(8)->Threads(64)->Threads(128)->Threads(256)
->ArgsProduct({{32, 64, 128, 256, 512},
{2,3,6}})->UseRealTime();
BENCHMARK(BM_WeightedRRScheduler)->Threads(1)->Threads(8)->Threads(64)->Threads(128)->Threads(256)
->ArgsProduct({{32, 64, 128, 256, 512},
{2,3,6}})->UseRealTime();
BENCHMARK_MAIN();