Derecho  0.9
Distributed systems toolkit for RDMA
performance.cpp
Go to the documentation of this file.
2 #include <derecho/conf/conf.hpp>
3 #include <iostream>
4 #include <time.h>
5 #define NUM_APP_ARGS (1)
6 
7 int main(int argc, char** argv) {
8  if((argc < (NUM_APP_ARGS + 1)) || ((argc > (NUM_APP_ARGS + 1)) && strcmp("--", argv[argc - NUM_APP_ARGS - 1]))) {
9  std::cerr << "Usage: " << argv[0] << " [ derecho-config-list -- ] <aio|bio>" << std::endl;
10  return -1;
11  }
12 
13  bool use_aio = false;
14  if(strcmp("aio", argv[argc - NUM_APP_ARGS]) == 0) {
15  use_aio = true;
16  } else if(strcmp("bio", argv[argc - NUM_APP_ARGS]) != 0) {
17  std::cerr << "unrecognized argument:" << argv[argc - NUM_APP_ARGS] << ". Using bio (blocking io) instead." << std::endl;
18  }
19 
20  struct timespec t_start, t_end;
21  derecho::Conf::initialize(argc, argv);
22  std::cout << "Starting object store service..." << std::endl;
23  // oss - objectstore service
25  [&](const objectstore::OID& oid, const objectstore::Object& object) {
26  //std::cout << "watcher: " << oid << "->" << object << std::endl;
27  });
28  // print some message
29  std::cout << "Object store service started. Is replica:" << std::boolalpha << oss.isReplica()
30  << std::noboolalpha << "." << std::endl;
31 
32  int runtime = 60 * 1000; // approximate runtime
33  int num_msg = 10000; // num_msg sent for the trial run
35  int msg_size = max_msg_size - 128;
36  if(msg_size > 2000000) {
37  num_msg = 5000;
38  }
39  char odata[msg_size];
40  srand(time(0));
41  for(int i = 0; i < msg_size; i++) {
42  odata[i] = '1' + (rand() % 74);
43  }
44  // create a pool of objects
45  std::vector<objectstore::Object> objpool;
46  for(int i = 0; i < num_msg; i++) {
47  objpool.push_back(objectstore::Object(i, odata, msg_size + 1));
48  }
49 
50  // trial run to get an approximate number of objects to reach runtime
51  clock_gettime(CLOCK_REALTIME, &t_start);
52  if(use_aio) {
53  for(int i = 0; i < num_msg; i++) {
54  oss.aio_put(objpool[i]);
55  }
56  } else {
57  for(int i = 0; i < num_msg; i++) {
58  oss.bio_put(objpool[i]);
59  }
60  }
61  oss.bio_get(num_msg - 1);
62  clock_gettime(CLOCK_REALTIME, &t_end);
63 
64  long long int nsec = (t_end.tv_sec - t_start.tv_sec) * 1000000000 + (t_end.tv_nsec - t_start.tv_nsec);
65  double msec = (double)nsec / 1000000;
66 
67  int multiplier = 1;
68  if(msec < runtime) {
69  multiplier = ceil(runtime / msec);
70 
71  // real benchmarking starts
72  clock_gettime(CLOCK_REALTIME, &t_start);
73  if(use_aio) {
74  for(int i = 0; i < num_msg * multiplier; i++) {
75  oss.aio_put(objpool[i % num_msg]);
76  }
77  } else {
78  for(int i = 0; i < num_msg * multiplier; i++) {
79  oss.bio_put(objpool[i % num_msg]);
80  }
81  }
82  oss.bio_get(num_msg - 1);
83  clock_gettime(CLOCK_REALTIME, &t_end);
84 
85  nsec = (t_end.tv_sec - t_start.tv_sec) * 1000000000 + (t_end.tv_nsec - t_start.tv_nsec);
86  msec = (double)nsec / 1000000;
87  }
88  double thp_mBps = ((double)max_msg_size * num_msg * multiplier * 1000) / nsec;
89  double thp_ops = ((double)num_msg * multiplier * 1000000000) / nsec;
90  std::cout << "timespan:" << msec << " millisecond." << std::endl;
91  std::cout << "throughput:" << thp_mBps << "MB/s." << std::endl;
92  std::cout << "throughput:" << thp_ops << "op/s." << std::endl;
93  std::cout << std::flush;
94  oss.leave();
95 }
#define CONF_SUBGROUP_DEFAULT_MAX_PAYLOAD_SIZE
Definition: conf.hpp:38
static IObjectStoreService & getObjectStoreService(int argc, char **argv, const ObjectWatcher &ow={})
virtual const bool isReplica()=0
#define NUM_APP_ARGS
Definition: performance.cpp:5
int argc
int main(int argc, char **argv)
Definition: performance.cpp:7
static void initialize(int argc, char *argv[], const char *conf_file=nullptr)
Definition: conf.cpp:67
char ** argv
uint64_t OID
Definition: Object.hpp:70
const uint64_t getConfUInt64(const std::string &key)
Definition: conf.cpp:134