diff options
-rw-r--r-- | include/hotstuff/client.h | 21 | ||||
-rwxr-xr-x | scripts/run_client.sh | 2 | ||||
-rw-r--r-- | scripts/thr_hist.py | 30 | ||||
-rw-r--r-- | src/hotstuff_client.cpp | 23 |
4 files changed, 65 insertions, 11 deletions
diff --git a/include/hotstuff/client.h b/include/hotstuff/client.h index 447a9db..d61d9e7 100644 --- a/include/hotstuff/client.h +++ b/include/hotstuff/client.h @@ -29,23 +29,36 @@ class CommandDummy: public Command { uint32_t cid; uint32_t n; uint256_t hash; +#if HOTSTUFF_CMD_DMSIZE > 0 + uint8_t payload[HOTSTUFF_CMD_DMSIZE]; +#endif + uint256_t compute_hash() { + DataStream s; + s << cid << n; + return s.get_hash(); + } public: - CommandDummy() {} - ~CommandDummy() override {} CommandDummy(uint32_t cid, uint32_t n): - cid(cid), n(n), hash(salticidae::get_hash(*this)) {} + cid(cid), n(n), hash(compute_hash()) {} void serialize(DataStream &s) const override { s << cid << n; +#if HOTSTUFF_CMD_DMSIZE > 0 + s.put_data(payload, payload + HOTSTUFF_CMD_DMSIZE); +#endif } void unserialize(DataStream &s) override { s >> cid >> n; - hash = salticidae::get_hash(*this); +#if HOTSTUFF_CMD_DMSIZE > 0 + auto base = s.get_data_inplace(HOTSTUFF_CMD_DMSIZE); + memmove(payload, base, HOTSTUFF_CMD_DMSIZE); +#endif + hash = compute_hash(); } const uint256_t &get_hash() const override { diff --git a/scripts/run_client.sh b/scripts/run_client.sh index 92d3add..9e7d1db 100755 --- a/scripts/run_client.sh +++ b/scripts/run_client.sh @@ -194,7 +194,7 @@ function start_all { local ip="$(get_ip_by_id $rid)" local pport="$(get_peer_port_by_id $rid)" local cport="$(get_client_port_by_id $rid)" - local rworkdir="$remote_base/$workdir/${i}" + local rworkdir="$remote_base/$workdir/${j}" ( echo "Starting a client @ $cip, connecting to server #$rid @ $ip:$cport" _remote_load "$workdir" "$rworkdir" "$cip" diff --git a/scripts/thr_hist.py b/scripts/thr_hist.py index c5f2a72..6f385e5 100644 --- a/scripts/thr_hist.py +++ b/scripts/thr_hist.py @@ -1,8 +1,24 @@ import sys import re import argparse +import numpy as np from datetime import datetime, timedelta +def remove_outliers(x, outlierConstant = 1.5): + a = np.array(x) + upper_quartile = np.percentile(a, 75) + lower_quartile = np.percentile(a, 25) + IQR = (upper_quartile - lower_quartile) * outlierConstant + quartileSet = (lower_quartile - IQR, upper_quartile + IQR) + resultList = [] + removedList = [] + for y in a.tolist(): + if y >= quartileSet[0] and y <= quartileSet[1]: + resultList.append(y) + else: + removedList.append(y) + return (resultList, removedList) + def str2datetime(s): parts = s.split('.') dt = datetime.strptime(parts[0], "%Y-%m-%d %H:%M:%S") @@ -23,20 +39,21 @@ if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--interval', type=float, default=1, required=False) parser.add_argument('--output', type=str, default="hist.png", required=False) + parser.add_argument('--plot', action='store_true') args = parser.parse_args() - commit_pat = re.compile('([^[].*) \[hotstuff info\] ([0-9.]*) [0-9.]*$') + commit_pat = re.compile('([^[].*) \[hotstuff info\] ([0-9.]*)$') interval = args.interval begin_time = None next_begin_time = None cnt = 0 - lat = 0 + lats = [] timestamps = [] values = [] for line in sys.stdin: m = commit_pat.match(line) if m: timestamps.append(str2datetime(m.group(1))) - lat += float(m.group(2)) + lats.append(float(m.group(2))) timestamps.sort() for timestamp in timestamps: if begin_time and timestamp < next_begin_time: @@ -49,5 +66,8 @@ if __name__ == '__main__': cnt = 1 values.append(cnt) print(values) - print("lat = {:.3f}ms".format(lat / len(timestamps) * 1e3)) - plot_thr(args.output) + print("lat = {:.3f}ms".format(sum(lats) / len(lats) * 1e3)) + lats, _ = remove_outliers(lats) + print("lat = {:.3f}ms".format(sum(lats) / len(lats) * 1e3)) + if args.plot: + plot_thr(args.output) diff --git a/src/hotstuff_client.cpp b/src/hotstuff_client.cpp index 62b13ed..390149f 100644 --- a/src/hotstuff_client.cpp +++ b/src/hotstuff_client.cpp @@ -1,5 +1,6 @@ #include <cassert> #include <random> +#include <signal.h> #include "salticidae/type.h" #include "salticidae/netaddr.h" #include "salticidae/network.h" @@ -42,6 +43,7 @@ struct Request { std::unordered_map<ReplicaID, MsgNetwork<opcode_t>::conn_t> conns; std::unordered_map<const uint256_t, Request> waiting; std::vector<NetAddr> replicas; +std::vector<std::pair<struct timeval, double>> elapsed; MsgNetwork<opcode_t> mn(eb, 10, 10, 4096); void set_proposer(ReplicaID rid) { @@ -97,7 +99,9 @@ void client_resp_cmd_handler(MsgRespCmd &&msg, MsgNetwork<opcode_t>::Conn &) { std::string(fin).c_str(), et.elapsed_sec, et.cpu_elapsed_sec); #else - HOTSTUFF_LOG_INFO("%.6f %.6f", et.elapsed_sec, et.cpu_elapsed_sec); + struct timeval tv; + gettimeofday(&tv, nullptr); + elapsed.push_back(std::make_pair(tv, et.elapsed_sec)); #endif waiting.erase(it); try_send(); @@ -108,8 +112,16 @@ std::pair<std::string, std::string> split_ip_port_cport(const std::string &s) { return std::make_pair(ret[0], ret[1]); } +void signal_handler(int) { + throw HotStuffError("got terminal signal"); +} + int main(int argc, char **argv) { Config config("hotstuff.conf"); + + signal(SIGTERM, signal_handler); + signal(SIGINT, signal_handler); + auto opt_idx = Config::OptValInt::create(0); auto opt_replicas = Config::OptValStrVec::create(); auto opt_max_iter_num = Config::OptValInt::create(100); @@ -152,6 +164,15 @@ int main(int argc, char **argv) { eb.dispatch(); } catch (HotStuffError &e) { HOTSTUFF_LOG_ERROR("exception: %s", std::string(e).c_str()); +#ifdef HOTSTUFF_ENABLE_BENCHMARK + for (const auto &e: elapsed) + { + char fmt[64]; + struct tm *tmp = localtime(&e.first.tv_sec); + strftime(fmt, sizeof fmt, "%Y-%m-%d %H:%M:%S.%%06u [hotstuff info] %%.6f\n", tmp); + fprintf(stderr, fmt, e.first.tv_usec, e.second); + } +#endif } return 0; } |