Skip to content

Commit bedb530

Browse files
PaulRalnikovAz3git
andauthored
FEAT: add connections & flows summary (#529)
closes #528 closes #520 --------- Co-authored-by: Alexey Zharkov <62723911+Az3git@users.noreply.github.com>
1 parent 42b42ca commit bedb530

26 files changed

Lines changed: 321 additions & 79 deletions

File tree

configs/fat-tree/network.yml

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,36 @@ presets:
44
default-flow:
55
type: tcp
66
metrics_filters:
7-
rtt: true
7+
rtt: false
88
reordering: false
99
delivery_rate: false
10-
10+
1111
default-connection:
1212
type: mplb-connection
1313
mplb:
1414
type: single-cc
1515
packet-size: 1500B
16-
16+
17+
metrics_filters:
18+
fairness: false
19+
1720
cc:
1821
type: swift
19-
base_target: 36000ns
22+
base_target: 20000ns
23+
metrics_filters:
24+
cwnd: false
2025

2126
path-chooser:
2227
type: round-robin
2328
flows:
2429
flow-1:
2530
type: tcp
2631
preset-name: default-flow
27-
32+
2833
flow-2:
2934
type: tcp
3035
preset-name: default-flow
31-
36+
3237
flow-3:
3338
type: tcp
3439
preset-name: default-flow

configs/fat-tree/scenario.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,3 @@ scenario:
77
size: 5MB
88
repeat_count: 1
99
connections: ^connection.*
10-
repeat_interval: 500000ns

configs/fat-tree/topology.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
presets:
22
edge-host-link:
33
latency: 1000ns
4-
throughput: 1Gbps
4+
throughput: 10Gbps
55
ingress_buffer_size: 4096KB
66
egress_buffer_size: 4096KB
77
metrics_filters:
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
#include <cstdint>
3+
namespace sim {
4+
5+
using Port = std::uint32_t;
6+
7+
struct EndpointPorts {
8+
Port sender_port = 0;
9+
Port receriver_port = 0;
10+
11+
EndpointPorts(Port a_sender_port = 0, Port a_receiver_port = 0)
12+
: sender_port(a_sender_port), receriver_port(a_receiver_port) {}
13+
};
14+
15+
} // namespace sim
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#pragma once
2+
#include "endpoint_ports.hpp"
3+
#include "endpoints.hpp"
4+
5+
namespace sim {
6+
7+
struct FlowFourTuple : Endpoints, EndpointPorts {
8+
FlowFourTuple(Endpoints endpoints, EndpointPorts ports = {})
9+
: Endpoints(endpoints), EndpointPorts(ports) {}
10+
};
11+
12+
} // namespace sim

source/connection/flow/i_new_flow.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22

33
#include "device/interfaces/i_host.hpp"
4-
#include "endpoints.hpp"
4+
#include "flow_four_tuple.hpp"
55
#include "metrics/metrics_storage.hpp"
66
#include "metrics/metrics_table/i_metricable.hpp"
77
#include "packet_ack_info.hpp"
@@ -10,8 +10,7 @@
1010

1111
namespace sim {
1212

13-
struct FlowContext : Endpoints {
14-
using Endpoints::Endpoints;
13+
struct FlowContext : FlowFourTuple {
1514
SizeByte sent_size = SizeByte(0);
1615
SizeByte delivered_size = SizeByte(0);
1716
SizeByte retransmit_size = SizeByte(0);
@@ -20,6 +19,8 @@ struct FlowContext : Endpoints {
2019
std::optional<TimeNs> last_ack_receive_time = std::nullopt;
2120
utils::Statistics<TimeNs> rtt_statistics;
2221
utils::Statistics<SpeedGbps> delivery_rate_statistics;
22+
23+
FlowContext(FlowFourTuple four_tuple) : FlowFourTuple(four_tuple) {}
2324
};
2425

2526
// Transport layer interface for reliable data delivery along single physical
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include "new_flows_summary.hpp"
2+
3+
#include "utils/filesystem.hpp"
4+
5+
namespace sim {
6+
NewFlowsSummary::NewFlowsSummary(const utils::IdTable<INewFlow>& flows_table) {
7+
for (const auto& [id, flow] : flows_table) {
8+
m_flows_contexts.emplace(id, flow->get_context());
9+
}
10+
}
11+
12+
void NewFlowsSummary::write_to_csv(std::filesystem::path output_path) const {
13+
utils::create_all_directories(output_path);
14+
std::ofstream out(output_path);
15+
if (!out) {
16+
throw std::runtime_error("Failed to create file for summary");
17+
}
18+
out << "Flow id"
19+
<< ", Sent size (bytes)"
20+
<< ", Delivered size (bytes)"
21+
<< ", Overhead (%)"
22+
<< ", Retransmit size (bytes)"
23+
<< ", Effective delivery rate (Gbps)"
24+
<< ", Delivery rate (Gbps)"
25+
<< ", FCT (ns)\n";
26+
for (const auto& [flow_id, ctx] : m_flows_contexts) {
27+
TimeNs fct =
28+
(ctx.last_ack_receive_time.has_value() && ctx.start_time.has_value()
29+
? ctx.last_ack_receive_time.value() - ctx.start_time.value()
30+
: TimeNs(0));
31+
32+
double overhead = ctx.delivered_size != SizeByte(0)
33+
? (ctx.sent_size / ctx.delivered_size - 1) * 100
34+
: std::nan("");
35+
// Effective delivery rate is average delivery rate calculated on the
36+
// spot (when connection is active) so does not include incative time
37+
// segments
38+
SpeedGbps effective_delivery_rate =
39+
ctx.delivery_rate_statistics.get_mean().value_or(SpeedGbps(0.0));
40+
41+
constexpr static double EPS = 1e-8;
42+
43+
SpeedGbps delivery_rate =
44+
(std::fabs(fct.value()) > EPS ? SpeedGbps(ctx.delivered_size / fct)
45+
: SpeedGbps(0.0));
46+
47+
out << flow_id;
48+
out << ", " << ctx.sent_size;
49+
out << ", " << ctx.delivered_size;
50+
out << ", " << overhead;
51+
out << ", " << ctx.retransmit_size;
52+
out << ", " << effective_delivery_rate;
53+
out << ", " << delivery_rate;
54+
out << ", " << fct;
55+
out << "\n";
56+
}
57+
}
58+
59+
} // namespace sim
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#pragma once
2+
#include "../i_new_flow.hpp"
3+
#include "utils/id_table.hpp"
4+
#include <filesystem>
5+
6+
namespace sim {
7+
8+
class NewFlowsSummary {
9+
public:
10+
explicit NewFlowsSummary(const utils::IdTable<INewFlow>& flows_table);
11+
12+
void write_to_csv(std::filesystem::path output_path) const;
13+
14+
private:
15+
std::unordered_map<Id, FlowContext> m_flows_contexts;
16+
};
17+
18+
} // namespace sim

source/connection/flow/tcp/new_tcp_flow.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,20 @@ namespace sim {
99
std::string NewTcpFlow::m_packet_type_label = "type";
1010

1111
std::shared_ptr<NewTcpFlow> NewTcpFlow::create_shared(
12-
Id a_id, std::shared_ptr<IHost> a_sender, std::shared_ptr<IHost> a_receiver,
13-
bool a_ecn_capable, RTO a_rto, TcpFlowMetricsFilters a_metrics_flags) {
12+
Id a_id, FlowFourTuple a_four_tuple, bool a_ecn_capable, RTO a_rto,
13+
TcpFlowMetricsFilters a_metrics_flags) {
1414
return std::shared_ptr<NewTcpFlow>(
15-
new NewTcpFlow(std::move(a_id), a_sender, a_receiver, a_ecn_capable,
15+
new NewTcpFlow(std::move(a_id), std::move(a_four_tuple), a_ecn_capable,
1616
std::move(a_rto), std::move(a_metrics_flags)));
1717
}
1818

1919
void NewTcpFlow::send(std::vector<PacketInfo> packets_info) {
2020
if (packets_info.empty()) {
2121
return;
2222
}
23+
if (!m_context.start_time.has_value()) {
24+
m_context.start_time = Scheduler::get_instance().get_current_time();
25+
}
2326
auto sender = m_context.sender;
2427
auto receiver = m_context.receiver;
2528
for (auto info : packets_info) {
@@ -52,11 +55,10 @@ MetricsTable NewTcpFlow::get_metrics_table() const {
5255
void NewTcpFlow::write_inner_metrics(
5356
[[maybe_unused]] std::filesystem::path output_dir) const {};
5457

55-
NewTcpFlow::NewTcpFlow(Id a_id, std::shared_ptr<IHost> a_sender,
56-
std::shared_ptr<IHost> a_receiver, bool a_ecn_capable,
58+
NewTcpFlow::NewTcpFlow(Id a_id, FlowFourTuple a_four_tuple, bool a_ecn_capable,
5759
RTO a_rto, TcpFlowMetricsFilters a_metrics_flags)
5860
: m_id(std::move(a_id)),
59-
m_context(a_sender, a_receiver),
61+
m_context(a_four_tuple),
6062
m_ecn_capable(a_ecn_capable),
6163
m_rto(std::move(a_rto)),
6264
m_metrics({std::make_shared<MetricsStorage>(),
@@ -86,6 +88,8 @@ Packet NewTcpFlow::create_data_packet(PacketInfo info,
8688

8789
packet.data_id = std::move(info.id);
8890
packet.source_id = sender->get_id();
91+
packet.sender_port = m_context.sender_port;
92+
packet.receriver_port = m_context.receriver_port;
8993
packet.dest_id = receiver->get_id();
9094
packet.size = info.packet_size;
9195

@@ -134,7 +138,9 @@ void NewTcpFlow::process_data_packet(const Packet& data,
134138
m_packet_reordering.value());
135139
Packet ack = data;
136140
ack.source_id = m_context.receiver->get_id();
141+
ack.sender_port = m_context.receriver_port;
137142
ack.dest_id = m_context.sender->get_id();
143+
ack.receriver_port = m_context.sender_port;
138144
ack.size = SizeByte(1);
139145
ack.ttl = M_MAX_TTL;
140146
ack.flags.set_flag(m_packet_type_label, PacketType::ACK)
@@ -171,6 +177,7 @@ void NewTcpFlow::process_ack(const Packet& ack, SizeByte data_packet_size,
171177
m_id, ack.to_string()));
172178
return;
173179
}
180+
m_context.last_ack_receive_time = now;
174181

175182
m_context.delivered_size += data_packet_size;
176183

source/connection/flow/tcp/new_tcp_flow.hpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ class NewTcpFlow : public INewFlow,
2323
constexpr static inline TcpFlowMetricsFilters DEFAULT_METRICS_FLAGS = {};
2424

2525
static std::shared_ptr<NewTcpFlow> create_shared(
26-
Id a_id, std::shared_ptr<IHost> a_sender,
27-
std::shared_ptr<IHost> a_receiver,
28-
bool a_ecn_capable = DEFAULT_ECN_CAPABLE, RTO a_rto = DEFAULT_START_RTO,
26+
Id a_id, FlowFourTuple a_four_tuple, bool a_ecn_capable = true,
27+
RTO a_rto = DEFAULT_START_RTO,
2928
TcpFlowMetricsFilters a_metrics_flags = DEFAULT_METRICS_FLAGS);
3029

3130
virtual void send(std::vector<PacketInfo> packets_info) final;
@@ -40,9 +39,8 @@ class NewTcpFlow : public INewFlow,
4039
std::filesystem::path output_dir) const final;
4140

4241
private:
43-
NewTcpFlow(Id a_id, std::shared_ptr<IHost> a_sender,
44-
std::shared_ptr<IHost> a_receiver, bool a_ecn_capable, RTO a_rto,
45-
TcpFlowMetricsFilters a_metrics_flags);
42+
NewTcpFlow(Id a_id, FlowFourTuple a_four_tuple, bool a_ecn_capable,
43+
RTO a_rto, TcpFlowMetricsFilters a_metrics_flags);
4644

4745
Packet create_data_packet(PacketInfo info, std::shared_ptr<IHost> sender,
4846
std::shared_ptr<IHost> receiver);

0 commit comments

Comments
 (0)