tapasco_benchmark.cpp 5.01 KB
Newer Older
1
/**
2
 *  @file	tapasco_benchmark.cpp
3
4
5
6
7
8
9
10
11
12
13
14
15
 *  @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>
16
#include <tapasco_api.hpp>
17
18
19
20
#include <platform_api.h>
#include "CumulativeAverage.hpp"
#include "TransferSpeed.hpp"
#include "InterruptLatency.hpp"
21
#include "JobThroughput.hpp"
22
23
24
#include "json11.hpp"

using namespace std;
25
using namespace tapasco;
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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}
    }; }
};

Jens Korinth's avatar
Jens Korinth committed
41
42
43
struct interrupt_latency_t {
  size_t cycle_count;
  double latency_us;
44
45
  double min_latency_us;
  double max_latency_us;
Jens Korinth's avatar
Jens Korinth committed
46
47
  Json to_json() const { return Json::object {
      {"Cycle Count", static_cast<double>(cycle_count)},
48
49
50
      {"Avg Latency", latency_us},
      {"Min Latency", min_latency_us},
      {"Max Latency", max_latency_us}
Jens Korinth's avatar
Jens Korinth committed
51
52
    }; }
};
53

54
55
56
57
58
59
60
61
62
struct job_throughput_t {
  size_t num_threads;
  double jobs_per_sec;
  Json to_json() const { return Json::object {
      {"Number of threads", static_cast<double>(num_threads)},
      {"Jobs per second", jobs_per_sec}
    }; }
};

63
int main(int argc, const char *argv[]) {
64
65
66
  Tapasco tapasco;
  TransferSpeed tp { tapasco };
  InterruptLatency il { tapasco };
67
  JobThroughput jt { tapasco };
68
69
70
  struct utsname uts;
  uname(&uts);
  vector<Json> speed;
71
  struct transfer_speed_t ts;
Jens Korinth's avatar
Jens Korinth committed
72
73
  vector<Json> latency;
  struct interrupt_latency_t ls;
74
75
  vector<Json> jobs;
  struct job_throughput_t js;
76
77
78

  string platform = "vc709";
  if (argc < 2) {
79
    if (getenv("TAPASCO_PLATFORM") == NULL) {
80
      char n[256] { "" };
81
      cout << "Environment variable TAPASCO_PLATFORM is not set, guessing Platform ..." << endl;
82
83
84
85
      if (gethostname(n, 255))
        cerr << "Could not get host name, guessing vc709 Platform" << endl;
      else {
        cout << "Host name: " << n << endl;
86
87
88
89
90
91
        platform = n;
        if (string(n).compare("zed") == 0 || string(n).compare("zedboard") == 0)
          platform = "zedboard";
        if (string(n).compare("zc706") == 0)
          platform = "zc706";
        cout << "Guessing " << platform << " Platform" << endl;
92
      }
93
    } else platform = getenv("TAPASCO_PLATFORM");
94
95
  }

96
  // measure for chunk sizes 2^10 (1KiB) - 2^31 (2GB) bytes
97
98
  for (int i = 10; i < 32; ++i) {
    ts.chunk_sz = 1 << i;
99
100
101
    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);
102
103
104
105
106
107
108
109
110
    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;
    if (ts.speed_r > 0.0 || ts.speed_w > 0 || ts.speed_rw > 0) {
      Json json = ts.to_json();
      speed.push_back(json);
    } else break;
111
112
  }

Jens Korinth's avatar
Jens Korinth committed
113
114
115
116
  // measure average job roundtrip latency for clock cycles counts
  // between 2^0 and 2^31
  for (size_t i = 0; i < 32; ++i) {
    ls.cycle_count = 1UL << i;
117
    ls.latency_us  = il.atcycles(ls.cycle_count, 10, &ls.min_latency_us, &ls.max_latency_us);
Jens Korinth's avatar
Jens Korinth committed
118
    cout << "Latency @ " << ls.cycle_count << "cc runtime: " << ls.latency_us << " us" << endl;
119
120
    Json json = ls.to_json();
    latency.push_back(json);
Jens Korinth's avatar
Jens Korinth committed
121
  }
122

123
124
125
126
127
128
129
130
131
132
133
  size_t i = 1;
  double prev = -1;
  js.jobs_per_sec = -1;
  do {
    prev = js.jobs_per_sec;
    js.num_threads = i;
    js.jobs_per_sec = jt(i);
    ++i;
    jobs.push_back(js.to_json());
  } while (i <= 128 && (i <= 8 || js.jobs_per_sec > prev));

134
135
136
137
138
139
140
141
142
143
144
  // 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},
145
146
147
148
        {"Node", uts.nodename},
        {"Release", uts.release},
        {"Version", uts.version},
        {"Machine", uts.machine}
149
150
151
      }
    },
    {"Transfer Speed", speed},
Jens Korinth's avatar
Jens Korinth committed
152
    {"Interrupt Latency", latency},
153
    {"Job Throughput", jobs},
154
    {"Library Versions", Json::object {
Jens Korinth's avatar
Jens Korinth committed
155
        {"Tapasco API",  tapasco::tapasco_version()},
156
157
158
159
        {"Platform API", platform::platform_version()}
      }
    }
  };
160

161
162
  // dump it
  stringstream ss;
163
  ss << platform << ".benchmark";
164
165
166
167
168
169
  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 : */