Exclude previously buffered data from multipath utilization results

This commit is contained in:
evgeny committed 2026-10-22 23:31:02 +02:00
1 parent 6e350760d1
commit 439361cb52
1 file changed
+14 -7
+14 -7
View File
@@ -268,12 +268,13 @@ static uint64_t measure_rate(const struct profile* settings, unsigned count, uns
run_for(WARMUP_MS, 1, "warmup"); begin_measure();
uint64_t before[2] = {ep[0].bytes, ep[1].bytes};
run_for(SAMPLE_MS, 1, "steady");
uint64_t elapsed = get_time_us() - measure_start, rate = (ep[1].bytes-before[1]) * 8000 / elapsed;
uint64_t elapsed = get_time_us() - measure_start, rate = 0;
for (unsigned side = 0; side <= bidirectional; side++) {
uint64_t useful = (ep[1-side].bytes-before[1-side]) * 8000 / elapsed, capacity = 0;
uint64_t useful = (ep[1-side].bytes-before[1-side]) * 8000 / elapsed, capacity = 0, unique_total = 0;
for (unsigned p = 0; p < count; p++) if (mask & (1u << p)) {
uint64_t wire = dummynet_get_stats(channels[p], side)->sent_bytes * 8000 / elapsed;
uint64_t unique = traffic[side][p].rx_unique * 8000 / elapsed;
unique_total += traffic[side][p].rx_unique;
capacity += settings[p].kbps;
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "RATE %s dir=%u path=%u RTT=%u BWlim=%u wire=%llu unique=%llu kbps retries=%llu",
case_name, side, p, settings[p].rtt_ms, settings[p].kbps, (unsigned long long)wire,
@@ -281,8 +282,12 @@ static uint64_t measure_rate(const struct profile* settings, unsigned count, uns
expect(wire >= settings[p].kbps * 90 / 100, "channel wire utilization >=90%", wire, settings[p].kbps * 90 / 100);
expect(unique >= settings[p].kbps * 80 / 100, "channel unique DATA >=80%", unique, settings[p].kbps * 80 / 100);
}
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "GOODPUT %s dir=%u useful=%llu capacity=%llu kbps", case_name, side,
(unsigned long long)useful, (unsigned long long)capacity);
uint64_t fresh = unique_total * 8000 / elapsed;
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "GOODPUT %s dir=%u application=%llu fresh_DATA=%llu capacity=%llu kbps", case_name, side,
(unsigned long long)useful, (unsigned long long)fresh, (unsigned long long)capacity);
// Нельзя пройти за счёт выдачи фрагментов, накопленных до начала измерения.
if (fresh < useful) useful = fresh;
if (!side) rate = useful;
expect(useful >= capacity * 85 / 100, "application goodput >=85% capacity", useful, capacity * 85 / 100);
}
measuring = 0;
@@ -302,7 +307,7 @@ static void stalled(const struct profile* settings, unsigned count, unsigned bro
unsigned pending = 0;
fault_seq = 0;
while (get_time_us() < deadline) {
pending = 0;
pending = 0; fault_seq = 0;
for (struct ll_entry* entry = ep[0].conn->input_wait_ack->head; entry; entry = entry->next) {
struct INFLIGHT_PACKET* pkt = (struct INFLIGHT_PACKET*)entry;
if (!pkt->last_link || ((directions & 1) && traces[0][pkt->seq].first_rx)) continue;
@@ -363,12 +368,13 @@ int main(int argc, char** argv) {
"case,phase,time_ms,direction,path,rtt_tb,pacing_kbps,inflight,cwnd,conn_rtt_tb,jitter,send_q,recv_q,wire_bytes,unique_bytes,retries,channel_q,app_bytes,max_gap_us\n"); }
struct profile matrix[][3] = {
{{20,8000},{20,8000}}, {{20,2000},{20,8000}}, {{20,8000},{200,8000}},
{{20,2000},{200,8000}}, {{20,8000},{200,2000}}, {{20,2000},{80,8000},{200,2000}}
{{20,2000},{200,8000}}, {{20,8000},{200,2000}}, {{20,2000},{80,8000},{200,2000}}, {{20,2000},{80,8000}}
};
const char* names[] = {"equal", "bandwidth", "rtt", "fast-distant", "slow-distant", "three"};
const char* names[] = {"equal", "bandwidth", "rtt", "fast-distant", "slow-distant", "three", "bidirectional"};
size_t baseline = u_get_allocated_count();
for (unsigned n = 0; n < sizeof(names)/sizeof(names[0]); n++) {
if (argc > 1 && strcmp(argv[1], names[n])) continue;
bidirectional = n == 6;
case_name = names[n]; unsigned count = n == 5 ? 3 : 2;
uint64_t solo_sum = 0;
for (unsigned p = 0; p < count; p++) solo_sum += measure_rate(matrix[n], count, 1u << p);
@@ -386,6 +392,7 @@ int main(int argc, char** argv) {
for (unsigned n = 0; n < sizeof(faults)/sizeof(faults[0]); n++) {
if (argc > 1 && strcmp(argv[1], faults[n].name)) continue;
case_name = faults[n].name;
bidirectional = 0;
struct profile settings[] = {{20,8000},{20,8000},{20,2000}};
if (!strcmp(case_name, "slow-drop")) settings[1].rtt_ms = 200;
stalled(settings, faults[n].count, faults[n].broken, faults[n].directions, faults[n].mode, faults[n].sparse, faults[n].ms);