Skip to content

Commit 7977493

Browse files
author
root
committed
resolve conversations
1 parent 095dba2 commit 7977493

11 files changed

Lines changed: 111 additions & 82 deletions

File tree

source/parser/parse_utils.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,30 +84,31 @@ utils::StrExpected<SizeByte> parse_size(const std::string &size) {
8484
return std::unexpected(maybe_value_unit.error());
8585
}
8686

87-
auto [value, unit] = maybe_value_unit.value();
87+
auto [value_32, unit] = maybe_value_unit.value();
88+
uint64_t value_64 = static_cast<uint64_t>(value_32);
8889
if (unit == Bit::suffix) {
89-
return SizeByte(Size<Bit>(static_cast<uint64_t>(value)));
90+
return SizeByte(Size<Bit>(value_64));
9091
}
9192
if (unit == Byte::suffix) {
92-
return SizeByte(static_cast<uint64_t>(value));
93+
return SizeByte(value_64);
9394
}
9495
if (unit == KBit::suffix) {
95-
return SizeByte(Size<KBit>(static_cast<uint64_t>(value)));
96+
return SizeByte(Size<KBit>(value_64));
9697
}
9798
if (unit == KByte::suffix) {
98-
return SizeByte(Size<KByte>(static_cast<uint64_t>(value)));
99+
return SizeByte(Size<KByte>(value_64));
99100
}
100101
if (unit == MBit::suffix) {
101-
return SizeByte(Size<MBit>(static_cast<uint64_t>(value)));
102+
return SizeByte(Size<MBit>(value_64));
102103
}
103104
if (unit == MByte::suffix) {
104-
return SizeByte(Size<MByte>(static_cast<uint64_t>(value)));
105+
return SizeByte(Size<MByte>(value_64));
105106
}
106107
if (unit == GBit::suffix) {
107-
return SizeByte(Size<GBit>(static_cast<uint64_t>(value)));
108+
return SizeByte(Size<GBit>(value_64));
108109
}
109110
if (unit == GByte::suffix) {
110-
return SizeByte(Size<GByte>(static_cast<uint64_t>(value)));
111+
return SizeByte(Size<GByte>(value_64));
111112
}
112113
return std::unexpected("Unsupported size unit: " + unit);
113114
}

source/topology/link/i_link.hpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,17 @@
99
namespace sim {
1010

1111
struct LinkContext {
12+
struct ActivityTime {
13+
TimeNs first;
14+
TimeNs last;
15+
16+
TimeNs active_time() const { return last - first; }
17+
};
18+
1219
SpeedGbps speed;
1320
TimeNs latency;
14-
std::optional<TimeNs> m_first_activity_time = std::nullopt;
15-
std::optional<TimeNs> m_last_activiti_time = std::nullopt;
16-
SizeByte m_total_data = SizeByte(0ul);
21+
std::optional<ActivityTime> activity_time = std::nullopt;
22+
SizeByte total_data_transferred = SizeByte(0ul);
1723

1824
bool operator<(const LinkContext& ctx) const {
1925
return std::make_pair(speed, latency) <
@@ -55,6 +61,9 @@ class ILink : public Identifiable, public IMetricable {
5561
virtual SizeByte get_max_to_ingress_queue_size() const = 0;
5662

5763
virtual const LinkContext& get_ctx() const = 0;
64+
65+
protected:
66+
virtual void record_activity() = 0;
5867
};
5968

6069
} // namespace sim

source/topology/link/link.cpp

Lines changed: 24 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
#include <spdlog/fmt/fmt.h>
44

5-
#include <algorithm>
6-
75
#include "logger/logger.hpp"
86
#include "scheduler/scheduler.hpp"
97
#include "utils/filesystem.hpp"
@@ -32,6 +30,7 @@ void Link::schedule_arrival(const Packet& packet) {
3230
m_id, packet.to_string()));
3331
return;
3432
}
33+
record_activity();
3534

3635
if (empty_before_push) {
3736
start_head_packet_sending();
@@ -137,11 +136,9 @@ void Link::transmit() {
137136
return;
138137
}
139138

140-
TimeNs current_time = Scheduler::get_instance().get_current_time();
139+
record_activity();
141140

142-
if (!m_ctx.m_first_activity_time.has_value()) {
143-
m_ctx.m_first_activity_time = current_time;
144-
}
141+
TimeNs current_time = Scheduler::get_instance().get_current_time();
145142

146143
Scheduler::get_instance().add(
147144
current_time + m_ctx.latency,
@@ -163,14 +160,8 @@ void Link::arrive(const Packet& packet) {
163160
m_id, packet.to_string()));
164161
return;
165162
}
166-
163+
record_activity();
167164
m_to.lock()->notify_about_arrival();
168-
if (!m_ctx.m_last_activiti_time.has_value()) {
169-
m_ctx.m_last_activiti_time = std::make_optional<TimeNs>(0ul);
170-
}
171-
m_ctx.m_last_activiti_time.value() =
172-
std::max(m_ctx.m_last_activiti_time.value(),
173-
Scheduler::get_instance().get_current_time());
174165

175166
LOG_INFO("Packet arrived to the next device. Packet: " +
176167
packet.to_string());
@@ -183,49 +174,18 @@ void Link::start_head_packet_sending() {
183174
[link = shared_from_this()]() { link->transmit(); });
184175
}
185176

186-
void Link::write_queue_metrics_to_csv(std::ofstream& out,
187-
const LinkQueue& queue) const {
188-
if (queue.get_type() == LinkQueueType::FromEgress) {
189-
out << "Egress buffer (switch)\n";
190-
} else {
191-
out << "Ingress buffer (host)\n";
192-
}
193-
194-
out << "Maximal size"
195-
<< ", Average size"
196-
<< ", Peak size"
197-
<< ", Packets transmitted"
198-
<< ", Packets dropped"
199-
<< ", Drop percent\n";
200-
201-
std::optional<SizeByte> average_opt =
202-
queue.get_ctx().size_statistics.get_mean();
203-
SizeByte average =
204-
(average_opt.has_value() ? average_opt.value() : SizeByte(0ul));
205-
double drop_percent =
206-
queue.get_ctx().packets_dropped /
207-
static_cast<double>(queue.get_ctx().packets_dropped +
208-
queue.get_ctx().packets_transmitted);
209-
210-
out << queue.get_ctx().size << ", " << average << ", "
211-
<< queue.get_max_size() << ", " << queue.get_ctx().packets_transmitted
212-
<< ", " << queue.get_ctx().packets_dropped << ", " << drop_percent
213-
<< "\n\n";
214-
}
215-
216177
void Link::write_inner_metrics(std::filesystem::path output_dir) const {
217-
std::filesystem::path output_path = output_dir / "metrics.csv";
178+
std::filesystem::path output_path = output_dir / "summary.csv";
218179
utils::create_all_directories(output_path);
219180
std::ofstream out(output_path);
220181
if (!out) {
221182
throw std::runtime_error(fmt::format(
222-
"Failed to create file for summary: {}", output_path.string()));
183+
"Failed to create file for report of link '{}': (file path: {})",
184+
m_id, output_path.string()));
223185
}
224186
write_thoughput_to_csv(out);
225-
226-
write_queue_metrics_to_csv(out, m_to_ingress);
227-
228-
write_queue_metrics_to_csv(out, m_from_egress);
187+
m_to_ingress.write_queue_metrics_to_csv(out);
188+
m_from_egress.write_queue_metrics_to_csv(out);
229189
}
230190

231191
void Link::write_thoughput_to_csv(std::ofstream& out) const {
@@ -236,28 +196,36 @@ void Link::write_thoughput_to_csv(std::ofstream& out) const {
236196
<< ", Utilization"
237197
<< ", Latency\n";
238198

239-
if (!m_ctx.m_first_activity_time || !m_ctx.m_last_activiti_time) {
199+
if (!m_ctx.activity_time.has_value()) {
240200
out << m_ctx.speed << ", " << 0 << ", " << 0 << ", " << m_ctx.latency
241201
<< "\n\n";
242202
return;
243203
}
244204

245-
TimeNs elapsed_time = m_ctx.m_last_activiti_time.value() -
246-
m_ctx.m_first_activity_time.value();
205+
TimeNs elapsed_time = m_ctx.activity_time.value().active_time();
247206

248-
if (elapsed_time.value() == 0) {
207+
if (elapsed_time == TimeNs(0)) {
249208
out << m_ctx.speed << ", " << 0 << ", " << 0 << ", " << m_ctx.latency
250209
<< "\n\n";
251210
return;
252211
}
253212

254-
uint64_t actual = m_ctx.m_total_data.value() / elapsed_time.value();
213+
SpeedGbps actual = m_ctx.total_data_transferred / elapsed_time;
255214

256-
uint64_t utilization =
257-
(m_ctx.speed.value() == 0 ? 0 : actual / m_ctx.speed.value());
215+
double utilization =
216+
(m_ctx.speed == SpeedGbps(0) ? 0.0 : actual / m_ctx.speed);
258217

259218
out << m_ctx.speed << ", " << actual << ", " << utilization << ", "
260219
<< m_ctx.latency << "\n\n";
261220
}
262221

222+
void Link::record_activity() {
223+
TimeNs now = Scheduler::get_instance().get_current_time();
224+
if (!m_ctx.activity_time.has_value()) {
225+
m_ctx.activity_time = LinkContext::ActivityTime{now, now};
226+
} else {
227+
m_ctx.activity_time->last = now;
228+
}
229+
}
230+
263231
} // namespace sim

source/topology/link/link.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ class Link : public ILink, public std::enable_shared_from_this<Link> {
4949
virtual void write_inner_metrics(
5050
std::filesystem::path output_dir) const final;
5151

52+
protected:
53+
void record_activity() override;
54+
5255
private:
5356
Link(Id a_id, std::weak_ptr<IDevice> a_from, std::weak_ptr<IDevice> a_to,
5457
SpeedGbps a_speed, TimeNs a_delay,
@@ -68,9 +71,6 @@ class Link : public ILink, public std::enable_shared_from_this<Link> {
6871
// Schedule Transmit event
6972
void start_head_packet_sending();
7073

71-
void write_queue_metrics_to_csv(std::ofstream& out,
72-
const LinkQueue& queue) const;
73-
7474
void write_thoughput_to_csv(std::ofstream& out) const;
7575

7676
private:

source/topology/link/packet_queue/link_queue.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,46 @@ LinkQueueType LinkQueue::get_type() const { return m_type; }
5757

5858
const LinkQueueContext& LinkQueue::get_ctx() const { return m_ctx; }
5959

60+
void LinkQueue::write_queue_metrics_to_csv(std::ofstream& out) const {
61+
if (m_type == LinkQueueType::FromEgress) {
62+
out << "Egress buffer of " << m_link_id << "\n";
63+
} else {
64+
out << "Ingress buffer of " << m_link_id << "\n";
65+
}
66+
67+
out << "Maximal size"
68+
<< ", Average size"
69+
<< ", Peak size"
70+
<< ", Packets transmitted"
71+
<< ", Packets dropped"
72+
<< ", Drop percent\n";
73+
74+
const utils::Statistics<SizeByte> statistics = m_ctx.size_statistics;
75+
76+
SizeByte average = statistics.get_mean().value_or(SizeByte(0ul));
77+
78+
double drop_percent = 0;
79+
double total_packets =
80+
static_cast<double>(m_ctx.packets_dropped + m_ctx.packets_transmitted);
81+
if (total_packets > 0) {
82+
drop_percent = m_ctx.packets_dropped / total_packets;
83+
}
84+
85+
out << get_max_size();
86+
out << ", " << average;
87+
out << ", " << statistics.get_peak().value_or(SizeByte(0ul));
88+
out << ", " << m_ctx.packets_transmitted;
89+
out << ", " << m_ctx.packets_dropped;
90+
out << ", " << drop_percent;
91+
out << "\n\n";
92+
}
93+
6094
void LinkQueue::record_size() {
6195
TimeNs now = Scheduler::get_instance().get_current_time();
6296
SizeByte queue_size = m_queue.get_size();
6397
m_queue_size_storage->add_record(now, queue_size.value());
64-
m_ctx.size_statistics.add_record(m_queue.get_size());
98+
m_ctx.size_statistics.add_record(queue_size);
99+
m_ctx.size = queue_size;
65100
}
66101

67102
} // namespace sim

source/topology/link/packet_queue/link_queue.hpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@ class LinkQueue {
2525
LinkQueue(SizeByte a_max_size, Id a_link_id, LinkQueueType a_type);
2626
~LinkQueue() = default;
2727

28-
virtual bool push(const Packet& packet) final;
29-
virtual const Packet& front() const final;
30-
virtual Packet& front() final;
31-
virtual void pop() final;
32-
33-
virtual SizeByte get_max_size() const final;
34-
virtual LinkQueueType get_type() const final;
35-
virtual bool empty() const final;
28+
bool push(const Packet& packet);
29+
const Packet& front() const;
30+
Packet& front();
31+
void pop();
32+
33+
SizeByte get_max_size() const;
34+
LinkQueueType get_type() const;
35+
bool empty() const;
3636
const LinkQueueContext& get_ctx() const;
37+
void write_queue_metrics_to_csv(std::ofstream& out) const;
3738

38-
virtual std::shared_ptr<const MetricsStorage> get_queue_size_storage()
39-
const;
39+
std::shared_ptr<const MetricsStorage> get_queue_size_storage() const;
4040

4141
private:
4242
void record_size();

source/utils/statistics.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class Statistics {
3737
m_variance =
3838
m_variance * m_factor + (delta * delta) * (1 - m_factor);
3939
}
40+
if (!m_peak || record > *m_peak) {
41+
m_peak = record;
42+
}
4043
}
4144

4245
std::optional<T> get_last() const {
@@ -57,12 +60,15 @@ class Statistics {
5760
: std::nullopt);
5861
}
5962

63+
std::optional<T> get_peak() const { return m_peak; }
64+
6065
private:
6166
bool m_have_records;
6267
const double m_factor;
6368
double m_last;
6469
double m_mean;
6570
double m_variance;
71+
std::optional<T> m_peak;
6672
};
6773

6874
} // namespace utils

test/device/utils.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,6 @@ SizeByte TestLink::get_max_to_ingress_queue_size() const {
3636

3737
const Id& TestLink::get_id() const { return ""; }
3838

39+
void TestLink::record_activity() {}
40+
3941
} // namespace test

test/device/utils.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ class TestLink : public sim::ILink {
4848

4949
virtual const sim::LinkContext& get_ctx() const final { return m_ctx; }
5050

51+
protected:
52+
void record_activity() override;
53+
5154
private:
5255
std::weak_ptr<sim::IDevice> src;
5356
std::weak_ptr<sim::IDevice> dst;

test/switch/link_mock.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,5 @@ SizeByte LinkMock::get_max_to_ingress_queue_size() const {
4040
}
4141

4242
const Id& LinkMock::get_id() const { return ""; }
43+
44+
void LinkMock::record_activity() {}

0 commit comments

Comments
 (0)