tpc_benchmark.cpp 3.59 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/**
 *  @file	tpc_benchmark.cpp
 *  @brief	Benchmark application that generates a JSON file containing
 *              parameters for design space exploration. Also gives an overview
 *              of system performance.
 *  @author	J. Korinth, TU Darmstadt (jk@esa.cs.tu-darmstadt.de)
 **/
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <chrono>
#include <ctime>
#include <vector>
#include <sys/utsname.h>
#include <tpc_api.hpp>
#include <platform_api.h>
#include "CumulativeAverage.hpp"
#include "TransferSpeed.hpp"
#include "InterruptLatency.hpp"
#include "json11.hpp"

using namespace std;
using namespace tpc;
using namespace json11;

struct transfer_speed_t {
  size_t chunk_sz;
  double speed_r;
  double speed_w;
  double speed_rw;
  Json to_json() const { return Json::object {
      {"Chunk Size", static_cast<int>(chunk_sz)},
      {"Read", speed_r},
      {"Write", speed_w},
      {"ReadWrite", speed_rw}
    }; }
};


int main(int argc, const char *argv[]) {
  ThreadPoolComposer tpc;
  TransferSpeed tp { tpc };
  InterruptLatency il { tpc };
  struct utsname uts;
  uname(&uts);
  vector<Json> speed;
  struct transfer_speed_t ts;

  string platform = "vc709";
  if (argc < 2) {
    if (getenv("TPC_PLATFORM") == NULL) {
      char n[256] { "" };
      cout << "Environment variable TPC_PLATFORM is not set, guessing Platform ..." << endl;
      if (gethostname(n, 255))
        cerr << "Could not get host name, guessing vc709 Platform" << endl;
      else {
        cout << "Host name: " << n << endl;
	if (string(n).compare("zed") == 0 || string(n).compare("zedboard"))
	  platform = "zedboard";
	if (string(n).compare("zc706") == 0)
	  platform = "zc706";
	cout << "Guessing " << platform << " Platform" << endl;
      }
    } else platform = getenv("TPC_PLATFORM");
  }

  // measure for chunk sizes 2^8 - 2^31 (2GB) bytes
  for (int i = 8; i < 32; ++i) {
    ts.chunk_sz = 1 << i;
    ts.speed_r  = tp(ts.chunk_sz, TransferSpeed::OP_COPYFROM);
    ts.speed_w  = tp(ts.chunk_sz, TransferSpeed::OP_COPYTO);
    ts.speed_rw = tp(ts.chunk_sz, TransferSpeed::OP_COPYFROM | TransferSpeed::OP_COPYTO);
    cout << "Transfer speed @ chunk_sz = " << (ts.chunk_sz/1024) << " KiB:" 
         << " read " << ts.speed_r << " MiB/s" 
         << ", write: " << ts.speed_w << " MiB/s"
	 << ", r/w: " << ts.speed_rw << " MiB/s"
	 << endl;
    Json json = ts.to_json();
    speed.push_back(json);
  }

  // measure average job roundtrip latency in the interval 1us - 100ms
  double const rl = il(0);
  cout << "Latency @ random runtime between 1us-100ms: " << rl << " us" << endl;

  // record current time
  time_t tt = chrono::system_clock::to_time_t(chrono::system_clock::now());
  tm tm = *localtime(&tt);
  stringstream str;
  str << put_time(&tm, "%Y-%m-%d %H:%M:%S");

  // build JSON object
  Json benchmark = Json::object {
    {"Timestamp", str.str()},
    {"Host", Json::object {
        {"Operating System", uts.sysname},
	{"Node", uts.nodename},
	{"Release", uts.release},
	{"Version", uts.version},
	{"Machine", uts.machine}
      }
    },
    {"Transfer Speed", speed},
    {"Job Roundtrip Overhead", rl},
    {"Library Versions", Json::object {
        {"TPC API", tpc::tpc_version()},
        {"Platform API", platform::platform_version()}
      }
    }
  };
  
  // dump it
  stringstream ss;
  ss << getenv("TPC_HOME") << "/platform/" << platform << "/" << platform << ".benchmark";
  cout << "Dumping benchmark JSON to " << (argc >= 2 ? argv[1] : ss.str()) << endl;
  ofstream f(argc >= 2 ? argv[1] : ss.str());
  f << benchmark.dump();
  f.close();
}
/* vim: set foldmarker=@{,@} foldlevel=0 foldmethod=marker : */