Commit 2ed3e6df authored by Joanne Hugé's avatar Joanne Hugé

Move measure-analysis to other repo

parent 055487d6
## Packet transmission latency
### Shuttle to A20
#### Measures done with tracing and timestamps (some overhead):
**Without XDP:**
| **Latency measured** | **min** | **avg** | **max** |
| -------------------------------------- | ------- | ------- | ------- |
| IRQ -> RX SO_TIMESTAMP | 27us | 31us | 136us |
| RX SO_TIMESTAMP -> Userspace timestamp | 85us | 93us | 247us |
| IRQ -> Userspace timestamp | 112us | 124us | 383us |
**With XDP:**
IRQ -> XDP_REDIRECT : ~30us (more measures needs to be done)
#### Measures done with timestamps (little overhead):
| **Latency measured** | | **Duration** | **Packets number** | **Interval** | **min** | **avg** | **max** |
| -------------------------------------- | ------ | ------------ | ------------------ | ------------ | ------- | ------ | ------ |
| Shuttle timestamp -> A20 timestamp | XDP | 2h45 | 50 100 000 | 250us | 22us | 24us | 173us |
| Shuttle timestamp -> A20 timestamp | no XDP | | | | 88us | 88us | 300us |
| RX SO_TIMESTAMP (A20) | no XDP | | | | 67us | 172us | 173us |
| TX SO_TIMESTAMP -> (Shuttle) | no XDP | | | | 2us | 18us | 20us |
#### PTP path delay and master offset
| **Measure** | **min** | **avg** | **max** |
| ---------------------| ------- | ------- | ------- |
| Master offset | -42us | 0us | 71us |
| Path delay | 23us | 31us | 47us |
#!/usr/bin/env python3
import statistics
import json
import markdown_table
import argparse
import os
import parse
import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
from math import sqrt
class MeasureSetHandler:
measures_dir = "measures"
graphs_dir = "{}/graphs".format(measures_dir)
measure_sets_file_name = "measure_sets.json"
measure_sets_path = measures_dir + "/" + measure_sets_file_name
def __init__(self):
with open(MeasureSetHandler.measure_sets_path) as measure_sets_file:
self.measure_sets = json.load(measure_sets_file)
self.load_report_info()
def __str__(self):
s = "List of measures:\n\n"
id_strs = []
for measure_set in self.measure_sets:
id_strs.append(" {} : {}".format(measure_set, self.measure_sets[measure_set]['ids']))
max_id_str_len = max([ len(s) for s in id_strs ])
for i, measure_set in enumerate(self.measure_sets):
next_id_str = self.measure_sets[measure_set]['next_id']
next_id_str = "{} (Next id: {})\n".format(" " * (max_id_str_len + 5 - len(id_strs[i])), next_id_str)
s+= id_strs[i] + next_id_str
return s
def load_report_info(self):
with open("report-info") as f:
s = "".join([l for l in f])
s = s.split("#Report description\n\n")[1]
(self.report_description, s) = s.split("\n\n#Metadata\n\n")
(metadata_text, s) = s.split("\n\n#Ignored metadata\n\n")
metadata_text = metadata_text.split("\n\n##")[1:]
self.metadata_names = {}
self.metadata_defvals = {}
self.metadata_descriptions = {}
for m in metadata_text:
(abbreviation, w) = m.split("\nDefault value: ")
(default_value, w) = w.split("\nShort name: ")
(short_name, description) = w.split("\nDescription: ")
self.metadata_names[abbreviation] = short_name
self.metadata_defvals[abbreviation] = default_value
self.metadata_descriptions[abbreviation] = description
(ignored_metadata, descriptions_text) = s.split("\n\n#Test types descriptions\n\n")
self.ignored_metadata = ignored_metadata.split(",")
self.type_descriptions = {}
self.type_ignored_metadata = {}
descriptions_text = descriptions_text.split("\n\n##")[1:]
for d in descriptions_text:
(type_name, w) = d.split("\n\nIgnored metadata: ")
(ignored_metadata, description) = d.split("\nDescription: ")
self.type_descriptions[type_name] = description
self.type_ignored_metadata[type_name] = ignored_metadata.split(",")
def save(self):
remove_list = []
for mtype in self.measure_sets:
if len(self.measure_sets[mtype]['ids']) == 0:
remove_list.append(mtype)
for mtype in remove_list:
del self.measure_sets[mtype]
with open(MeasureSetHandler.measure_sets_path, 'w') as measure_sets_file:
json.dump(self.measure_sets, measure_sets_file)
def import_from_file(self, path, cyclictest=False, ping=False, user_input=False, file_input=None):
measure_sets = []
with open(path) as infile:
if cyclictest:
data = MeasureSet.parse_cyclictest(infile)
elif ping:
data = MeasureSet.parse_ping(infile)
else:
data = json.load(infile)
if file_input != None:
with open(file_input) as metadata_file:
metadata = json.load(metadata_file)
for measure_set_data in data['measure_sets']:
measure_set = MeasureSet(self.metadata_defvals)
measure_set.import_from_json_data(measure_set_data, user_input=user_input)
if file_input != None:
measure_set.update_metadata(metadata, []);
measure_sets.append(measure_set)
return measure_sets
def get_measure_set(self, measure_name):
measure_path = "{}/{}.json".format(self.measures_dir, measure_name)
measure_set = self.import_from_file(measure_path)[0]
return measure_set
def add_measure_set(self, measure_set):
measure_set.compute_duration()
mtype = measure_set.measure_type
if mtype not in self.measure_sets:
self.measure_sets[mtype] = {'ids': [], 'next_id': 0}
next_id = self.measure_sets[mtype]['next_id']
measure_file_name = "{}/{}{}.json".format(MeasureSetHandler.measures_dir, mtype, next_id)
measure_set.export_to_json(measure_file_name)
self.measure_sets[mtype]['ids'].append(next_id)
self.measure_sets[mtype]['next_id'] += 1
self.save()
print("Saved measure as {}{}".format(mtype, next_id))
def remove_measure_set(self, mtype, mid):
if mtype in self.measure_sets and mid in self.measure_sets[mtype]['ids']:
self.measure_sets[mtype]['ids'].remove(mid)
measure_file_name = "{}/{}{}.json".format(MeasureSetHandler.measures_dir, mtype, mid)
os.remove(measure_file_name)
self.save()
print("Removed measure {}{}".format(mtype, mid))
else:
print("{}{} doesn't exist".format(mtype, mid))
def remove_mtype(self, mtype):
measures_removed = 0
if mtype not in self.measure_sets:
print("No type named {}".format(mtype))
return
ids = [index for index in self.measure_sets[mtype]['ids']]
for mid in ids:
self.remove_measure_set(mtype, mid)
measures_removed += 1
if measures_removed:
print("Removed {} measures of the type {}".format(measures_removed, mtype))
else:
print("No measures were removed")
def update_metadata(self, mtype, mid, metadata, removed_metadata):
if mtype in self.measure_sets and mid in self.measure_sets[mtype]['ids']:
measure_set = self.get_measure_set("{}{}".format(mtype, mid))
measure_set.update_metadata(metadata, removed_metadata)
measure_file_name = "{}/{}{}.json".format(MeasureSetHandler.measures_dir, mtype, mid)
measure_set.export_to_json(measure_file_name)
else:
print("{}{} doesn't exist".format(mtype, mid))
def modify_metadata(self, mtype, mid=-1):
update_all = (mid == -1)
if mtype in self.measure_sets:
measure_ids = self.measure_sets[mtype]['ids']
else:
print("There are no measures of type {}".format(mtype))
return
if update_all:
mid = measure_ids[0]
if mtype in self.measure_sets and mid in measure_ids:
measure_set = self.get_measure_set("{}{}".format(mtype, mid))
metadata, removed_metadata = measure_set.input_metadata()
self.update_metadata(mtype, mid, metadata, removed_metadata)
if update_all:
for measure_id in measure_ids:
self.update_metadata(mtype, measure_id, metadata, removed_metadata)
else:
print("{}{} doesn't exist".format(mtype, mid))
def remove_all(self):
while True:
if len(self.measure_sets) == 0:
break
mtype = [x for x in self.measure_sets][0]
while True:
if mtype not in self.measure_sets:
break
if len(self.measure_sets[mtype]['ids']) == 0:
break
mid = self.measure_sets[mtype]['ids'][0]
print(" Deleting {}{}...".format(mtype, mid))
self.remove_measure_set(mtype, mid)
print("Removed all measures")
def generate_graphs(self, metadata_masks):
# For each type of measure set
for mtype in self.measure_sets:
# List all the measures of this type
measures = []
mids = []
for mid in self.measure_sets[mtype]['ids']:
measure = self.get_measure_set("{}{}".format(mtype, mid))
# Measures with lost packets are not relevant to graph
if measure.metadata['lost_packets'] == "0":
if measure.props_type != 'minmaxavg':
measures.append(measure)
mids.append(mid)
if len(measures) == 0:
continue
# Get the type and number of properties, which are all identical for
# measures of the same type
props_type = measures[0].props_type
nb_props = len(measures[0].props)
# For each property draw a graph
for i in range(nb_props):
prop_name = measures[0].props_names[i]
subplots = []
metadata_infos = []
# Superimpose all the different measures of the same type and property type
for j, measure in enumerate(measures):
mid = mids[j]
graph_name = "{}{}".format(mtype, mid)
# Generate the plot name from the metadata mask
metadata_info = ["{}".format(measure.metadata[metadata_name]) for metadata_name in metadata_masks[mtype]]
metadata_infos.append(", ".join(metadata_info))
if props_type == 'histogram':
subplots.append(measure.generate_histogram(i, metadata_info))
else:
subplots.append(measure.generate_chrono_graph(i, metadata_info))
fig, ax = plt.gcf(), plt.gca()
# Set meta graph information
if props_type == 'histogram':
ax.set_xlabel('Latency (us)')
ax.set_ylabel('Percentage of latency samples (%)')
ax.set_title('{}, {} histogram'.format(mtype, prop_name))
else:
ax.set_xlabel('Time (us)')
ax.set_ylabel(prop_name)
ax.set_title('{}, {} graph'.format(mtype, prop_name))
plt.legend(subplots, metadata_infos)
#ax.legend(fancybox=True, framealpha=1, shadow=True, borderpad=1)
fig.set_size_inches(15.0, 8.0)
# Save the graph
plt.savefig("{}/{}{}.png".format(MeasureSetHandler.graphs_dir, mtype, prop_name))
plt.clf()
def generate_metadata_text(self):
metadata_masks = {}
common_metadata_strs = {}
for mtype in self.measure_sets:
metadata_mask = []
measures = []
for mid in self.measure_sets[mtype]['ids']:
measures.append(self.get_measure_set("{}{}".format(mtype, mid)))
if len(measures) == 0:
continue
first_metadata = measures[0].metadata
# Generate the metadata mask, by grouping the identical metadata
for measure in measures[1:]:
for metadata_name in measure.metadata:
if metadata_name not in self.ignored_metadata and metadata_name not in self.type_ignored_metadata[mtype] and metadata_name != 'lost_packets':
# If it is not already in the metadata mask
if metadata_name not in metadata_mask:
# If there are two different metadata, they are added to the mask
if measure.metadata[metadata_name] != first_metadata[metadata_name]:
metadata_mask.append(metadata_name)
metadata_masks[mtype] = metadata_mask
# Compute the identical metadata
common_metadata = []
for metadata_name in first_metadata:
if metadata_name not in self.ignored_metadata and metadata_name not in self.type_ignored_metadata[mtype] and metadata_name != 'lost_packets':
if metadata_name not in metadata_mask:
if metadata_name in self.metadata_names:
common_metadata.append("{}: {}".format(self.metadata_names[metadata_name], first_metadata[metadata_name]))
else:
common_metadata.append("{}: {}".format(metadata_name, first_metadata[metadata_name]))
common_metadata_strs[mtype] = ", ".join(common_metadata)
return (metadata_masks, common_metadata_strs)
def generate_report(self, include_graphs=True):
metadata_masks, common_metadata_strs = self.generate_metadata_text()
if include_graphs:
self.generate_graphs(metadata_masks)
with open("measure-report.md", 'w+') as report:
report.write("## Measurements\n\n")
report.write("{}\n\n".format(self.report_description))
report.write("### Description of the metadata associated to each test\n\n")
for abbr_name in self.metadata_descriptions:
if abbr_name not in self.ignored_metadata:
report.write("* **{}**: {}\n".format(abbr_name, self.metadata_descriptions[abbr_name]))
report.write("\n")
for mtype in self.measure_sets:
need_header = True
props_lens = []
report.write("### {} results\n\n".format(mtype))
# mtype description
if mtype in self.type_descriptions:
report.write('{}\n\n'.format(self.type_descriptions[mtype]))
# List all the measures of this type
measures = []
for mid in self.measure_sets[mtype]['ids']:
measure = self.get_measure_set("{}{}".format(mtype, mid))
measures.append(measure)
if len(measures) == 0:
continue
packet_measures = 'lost_packets' in measures[0].metadata
if packet_measures:
measures.sort(key=lambda x:x.metadata['lost_packets'])
first_metadata = measures[0].metadata
# Write the identical metadata before the table
report.write("**Common test metadata:** {}\n\n".format(common_metadata_strs[mtype]))
for measure in measures:
if need_header:
table_str, props_lens = measure.generate_table(packet_measures, headers=True, metadata_mask=metadata_masks[mtype])
report.write(table_str)
need_header = False
else:
report.write(measure.generate_table(packet_measures, headers=False, props_lens=props_lens, metadata_mask=metadata_masks[mtype])[0])
report.write("\n")
# Include the graphs
if include_graphs:
for i in range(len(measures[0].props)):
report.write('\n![alt text]({}/graphs/{}{}.png "{} Graph")\n'.format(MeasureSetHandler.measures_dir,
mtype,
measures[0].props_names[i],
mtype,
measures[0].props_names[i]))
report.write("\n")
report.write("\n")
with open("additional-measures.md") as additional_measures:
report.write("## Additional measures\n\n")
report.write("".join([l for l in additional_measures]))
def update_report_info(self):
for mtype in self.measure_sets:
for mid in self.measure_sets[mtype]['ids']:
measure = self.get_measure_set("{}{}".format(mtype, mid))
for abr in self.metadata_defvals:
if not abr in measure.metadata:
measure.metadata[abr] = self.metadata_defvals[abr]
measure_file_name = "{}/{}{}.json".format(MeasureSetHandler.measures_dir, mtype, mid)
measure.export_to_json(measure_file_name)
class MeasureSet:
def __init__(self, defvals):
# Default values
self.metadata = {}
for metadata_name in defvals:
self.metadata[metadata_name] = defvals[metadata_name]
self.props = []
self.props_name = []
self.units = []
def __str__(self):
return "Cols: " + str(self.props) + "\n"
def merge_metadata(metadata, new_metadata, removed_metadata):
metadata.update(new_metadata)
for metadata_name in removed_metadata:
metadata.pop(metadata_name, None)
return metadata
def update_metadata(self, metadata, removed_metadata):
self.metadata = MeasureSet.merge_metadata(self.metadata, metadata, removed_metadata)
def input_metadata(self):
metadata = {}
removed_metadata = []
metadata_name = ""
while True:
merged_metadata = MeasureSet.merge_metadata(self.metadata, metadata, removed_metadata)
print("Current metadata:\n")
for metadata_name in merged_metadata:
print(" {}: {}".format(metadata_name, merged_metadata[metadata_name]))
metadata_name = input('Enter metadata name (type "done" to exit): ')
if metadata_name == "done":
break
metadata_value = input('Enter metadata value (type "done" to exit, "delete" to delete current metadata, "cancel" to cancel current metadata): ')
if metadata_value == "done":
break
if metadata_value == "cancel":
continue
if metadata_value == "delete":
removed_metadata.append(metadata_name)
continue
metadata[metadata_name] = metadata_value
return (metadata, removed_metadata)
def add_metadata(self, measure_type, units, middle, metadata, user_input=False):
self.measure_type = measure_type
self.units = units
self.middle = int(middle)
self.metadata.update(metadata)
if user_input:
new_metadata, removed_metadata = self.input_metadata()
self.update_metadata(new_metadata, removed_metadata)
def add_chronological(self, props_names, props):
self.props = props
self.props_names = props_names
self.props_type = 'chronological'
self.max = [max(prop) for prop in props]
self.min = [min(prop) for prop in props]
self.avg = [statistics.mean(prop) for prop in props]
self.dev = [sqrt(statistics.variance(prop)) for prop in props]
def add_histogram(self, props_names, props):
self.props = props
self.props_names = props_names
self.props_type = 'histogram'
self.max = []
self.min = []
self.avg = []
self.dev = []
self.nb_measures = []
for prop in props:
enumerate_prop = list(enumerate(prop))
self.max.append(max(list(map(lambda x: (x[0] - self.middle) if x[1] else 0, enumerate_prop))))
self.min.append(min(map(lambda x: (x[0] - self.middle) if x[1] else self.max[-1], enumerate_prop)))
sum_prop = sum(prop)
self.nb_measures.append(sum_prop)
avg = sum(map(lambda x: abs(x[0] - self.middle)*x[1], enumerate_prop)) / sum_prop
avg_centered = sum(map(lambda x: x[0]*x[1], enumerate_prop)) / sum_prop
var = 0
for x, p in enumerate_prop:
var += p * x**2
var /= sum_prop
var -= avg_centered**2
self.avg.append(avg)
self.dev.append(sqrt(var))
def add_minmaxavg(self, props_names, props):
self.props = props
self.props_names = props_names
self.props_type = 'minmaxavg'
self.max = []
self.min = []
self.avg = []
self.dev = []
self.nb_measures = []
for prop in props:
min_v, max_v, avg_v, dev_v, nb_measures = prop
self.max.append(max_v)
self.min.append(min_v)
self.avg.append(avg_v)
self.dev.append(dev_v)
self.nb_measures.append(nb_measures)
def export_to_json(self, path):
with open(path, 'w') as outfile:
json.dump({'measure_sets': [
{'measure_type': self.measure_type,
'props_names': self.props_names,
'units': self.units,
'middle': self.middle,
'props': self.props,
'props_type': self.props_type,
'metadata': self.metadata}
]}, outfile)
def parse_ping(infile):
data = {}
data['measure_sets'] = []
lines = [line for line in infile]
s = lines[-2]
transmitted,s = s.split(" packets transmitted, ")
received,s = s.split(" received")
tmp,s = s.split("time ")
nb_minutes = int(s[:-3]) // (1000 * 60)
hours,minutes = nb_minutes // 60, nb_minutes % 60
s = lines[-1]
s = s.split(" = ")[1]
s = s.split(" ms")[0]
values = s.split("/")
values = [int(float(v) * 1000) for v in values]
min_rtt, avg_rtt, max_rtt, mdev_rtt = values
measure_set = {}
measure_set['props_type'] = 'minmaxavg'
measure_set['units'] = ['us']
measure_set['props'] = [(min_rtt, max_rtt, avg_rtt, mdev_rtt, transmitted)]
measure_set['metadata'] = {}
measure_set['metadata']['lost_packets'] = str(int(transmitted) - int(received))
measure_set['measure_type'] = 'ping_interval'
measure_set['props_names'] = ['ping RTT']
measure_set['metadata']['duration'] = "{}h{}".format(hours, minutes)
data['measure_sets'].append(measure_set)
return data
def parse_cyclictest(infile):
data = {}
data['measure_sets'] = []
lines = [line for line in infile]
while len(lines) > 0:
measure_set = {}
measure_set['props_type'] = 'histogram'
measure_set['metadata'] = {}
measure_set['metadata']['lost_packets'] = 0
i = 0
# Search histogram line
for line in lines:
# Searching for Histogram or histogram
if "istogram" in line:
if "Packet jitter histogram" in line:
measure_set['measure_type'] = 'packet_jitter'
measure_set['props_names'] = ['Packet jitter']
elif "RX timestamps histogram" in line:
measure_set['measure_type'] = 'packet_rx_timestamps'
measure_set['props_names'] = ['Packet RX timestamps']
elif "TX timestamps histogram" in line:
measure_set['measure_type'] = 'packet_tx_timestamps'
measure_set['props_names'] = ['Packet TX timestamps']
elif "RX latency histogram" in line:
measure_set['measure_type'] = 'packet_latency'
measure_set['props_names'] = ['Packet latency']
elif "RTT histogram" in line:
measure_set['measure_type'] = 'packet_rtt'
measure_set['props_names'] = ['Packet round trip time']
elif "Shuttle-A20" in line:
measure_set['measure_type'] = 'shuttle_a20_signal_jitter'
measure_set['props_names'] = ['edge to edge', 'period']
elif "Shuttle" in line:
measure_set['measure_type'] = 'shuttle_signal_jitter'
measure_set['props_names'] = ['Shuttle signal output jitter']
elif "Histogram" in line:
measure_set['measure_type'] = 'cyclictest_wake-up_latency'
measure_set['props_names'] = ['Wake-up latency']
break
i+=1
measure_set['props'] = [[] for x in measure_set['props_names']]
measure_set['units'] = ['us' for x in measure_set['props_names']]
lines = lines[i+1:]
i = 0
for prop_i in range(len(measure_set['props_names'])):
for line in lines:
if line[0] == '#':
break
j, x = parse.parse('{:d} {:d}', line)
measure_set['props'][prop_i].append(x)
i+=1
lines = lines[i:]
i = 0
for line in lines:
if ': ' not in line:
break
s,v = line.split(": ")
if "Duration" in s:
measure_set['metadata']['duration'] = v[:-1]
if "High kernel latencies" in s or "Invalid parameters" in s or "Missed deadlines" in s or "Lost packets" in s:
measure_set['metadata']['lost_packets'] += int(v)
i+=1
lines = lines[i:]
measure_set['metadata']['lost_packets'] = str(measure_set['metadata']['lost_packets'])
data['measure_sets'].append(measure_set)
if measure_set['measure_type'] == 'cyclictest_wake-up_latency':
break
return data
def compute_duration(self):
print(self.props_type)
if self.props_type == 'minmaxavg':
nb_packets = int(self.props[0][4])
else:
nb_packets = sum(self.props[0])
nb_us = int(self.metadata['i'][:-2]) * nb_packets
hours = int((nb_us / 10**6) / 3600)
minutes = int((nb_us / 10**6) / 60) % 60
self.metadata['duration'] = "{}h{}".format(hours, minutes)
def import_from_json_data(self, data, user_input=False):
measure_type = data['measure_type']
units = data['units']
metadata = data['metadata']
if 'middle' in data:
middle = data['middle']
else:
middle = 0
self.add_metadata(measure_type, units, middle, metadata, user_input)
props_names = data['props_names']
props = data['props']
if data['props_type'] == 'histogram':
self.add_histogram(props_names, props)
elif data['props_type'] == 'minmaxavg':
self.add_minmaxavg(props_names, props)
else:
self.add_chronological(props_names, props)
def generate_histogram(self, i, name):
bins = [i for i in range(self.min[i], self.max[i] + 1)]
vals = self.props[i][self.min[i] + self.middle : self.max[i] + self.middle + 1]
vals = [ (x * 100) / sum(vals) for x in vals]
min_val = max(vals) / 140
vals = list(map(lambda x: min_val if x != 0 and x < min_val else x, vals))
return plt.bar(bins, vals, alpha=0.4)
def generate_chrono_graph(self, i, name):
prop = self.props[i]
x = [i for i in range(len(prop))]
return plt.plot(x, prop)
def generate_table(self, packet_measures, headers=True, values=True, metadata_mask=[], props_lens=[]):
if headers == False and values == False:
return ""
table = []
if headers:
# Table headers
headers = ["Minimum", "Maximum", "Average", "Standard deviation"]
if packet_measures:
headers.append("Lost packets")
# Add a metadata information column if the metadata_mask isn't empty
if metadata_mask != []:
table += [["Metadata"] + headers]
table += [["**" + ", ".join(metadata_mask) + "**"] + ["**" + " - ".join(self.props_names) + "**"] * len(headers)]
else:
table += [headers]
table += [["**" + " - ".join(self.props_names) + "**"] * len(headers)]
if packet_measures:
table[-1][-1] = ""
if values:
m = [self.min, self.max, self.avg, self.dev]
values = [[ (format(m[i][j], '.1f') + self.units[j]) for j in range(len(m[0]))] for i in range(len(m))]
if metadata_mask != []:
metadata_info = ["{}".format(self.metadata[metadata_name]) for metadata_name in metadata_mask]
table += [["{} ".format(", ".join(metadata_info))] +
[" - ".join(values[i]) for i in range(len(values))]]
else:
table += [[" - ".join(values[i]) for i in range(len(values))]]
if packet_measures:
table[-1] += [self.metadata['lost_packets']]
if props_lens == []:
props_lens = [max([len(table[i][j]) for i in range(len(table))]) for j in range(len(table[0]))]
table = [[ table[i][j].ljust(props_lens[j]) for j in range(len(table[0]))] for i in range(len(table))]
table_str = ""
if headers:
table_str += " | ".join(table[0]) + "\n"
table_str += " | ".join([ ("-" * props_lens[i]) for i in range(len(props_lens)) ]) + "\n"
if values:
table_str += "\n".join([" | ".join(line) for line in table[1:]])
else:
table_str += "\n".join([" | ".join(line) for line in table])
return (table_str, props_lens)
def name_to_mtype_mid(file_name):
mid_start = 0
for c in range(len(file_name)-1, -1, -1):
if not str.isdigit(file_name[c]):
mid_start = c+1
break
mtype = file_name[:mid_start]
mid = int(file_name[mid_start:])
return (mtype, mid)
def parse_args():
parser = argparse
parser = argparse.ArgumentParser(description='Measure analysis')
parser.add_argument('-i', nargs=1, required=False, help='import json measures')
parser.add_argument('-c', action='store_true', required=False, help='parse cyclictest-like output (usable with client and server program\'s output)')
parser.add_argument('-p', action='store_true', required=False, help='parse ping output')
parser.add_argument('-I', nargs=1, required=False, help='import metadata file')
parser.add_argument('--remove', nargs=1, required=False, help='remove a measure')
parser.add_argument('--remove-type', nargs=1, required=False, help='remove all measures from a type')
parser.add_argument('--remove-all', action='store_true', help='remove all measure sets')
parser.add_argument('-m', nargs=1, required=False, help='modify the metadata of a measure')
parser.add_argument('-M', nargs=1, required=False, help='modify the metadata of all measures of a type')
parser.add_argument('-t', nargs='?', const='input_file', required=False, help='generate table')
parser.add_argument('-R', action='store_true', required=False, help='generate full measure report')
parser.add_argument('-G', action='store_true', required=False, help='generate all graphs')
parser.add_argument('-s', action='store_true', help='show measures')
parser.add_argument('-u', action='store_true', required=False, help='update data accordingly to report-info')
args = parser.parse_args()
ms_handler = MeasureSetHandler()
if args.remove is not None:
mtype, mid = name_to_mtype_mid(args.remove[0])
ms_handler.remove_measure_set(mtype, mid)
if args.remove_type is not None:
ms_handler.remove_mtype(args.remove_type[0])
if args.m is not None:
mtype, mid = name_to_mtype_mid(args.m[0])
ms_handler.modify_metadata(mtype, mid)
if args.M is not None:
mtype = str(args.M[0])
ms_handler.modify_metadata(mtype)
if args.i is not None:
if args.I is not None:
file_input = args.I[0]
user_input = False
else:
file_input = None
user_input = True
if not (args.p or args.c):
print("Select either -p or -c when importing")
parser.print_help()
exit()
measure_sets = ms_handler.import_from_file(args.i[0], cyclictest=bool(args.c), ping=bool(args.p), user_input=user_input, file_input=file_input)
for measure_set in measure_sets:
ms_handler.add_measure_set(measure_set)
elif args.t is not None and args.t != "input_file":
measure_set = ms_handler.get_measure_set(args.t)
print(measure_set.generate_table(True, True, {'board', 'linux_version', 'boot_params'})[0])
if args.R:
ms_handler.generate_report()
if args.u:
ms_handler.update_report_info()
if args.G:
ms_handler.generate_graphs()
if args.remove_all:
confirm = input("Are you sure all measure sets should be removed ? [Yes] / [No]: ")
if confirm == "Yes":
ms_handler.remove_all()
if args.s:
print(ms_handler)
parse_args()
## Measurements
This report was generated with the measure-analysis.py script.
JSON formated measures were imported in the measures folder using the import functionnality of the script, this report was then generated using these measures.
Metadata is included with the measures, such as the kernel version used, the boot parameters passed, various others parameters specific to the measure, etc...
Measures measuring the same propriety are grouped together in tables and graphs, and are identified by their diverging metadatas. This is useful to analyse the effect of specific parameters on the measured propriety.
### Description of the metadata associated to each test
* **dev**: Device on which the tests were run
* **ker**: Linux kernel version used
* **prio**: Priority of the real-time thread
* **i**: Interval between each packet transmission
* **boot_p**: Boot Parameters passed to u-boot
* **delta**: ETF qdisc delta value
* **load**: External device and processor load during the test
* **duration**: Duration of the test
* **speed**: Ethernet speed in Mb/s
* **etf_offset**: When a packet\s txtime is scheduled, the txtime set is the current time offset by etf_offset
* **route**: How the boards are connected. switch means they are connected by a switch (cheap, unmanaged), E2E
* **qdisc**: qdisc used to send packets
* **client**: Device which sent the packets
* **server**: Device which received the packets
* **XDP**: Were XDP sockets used
* **delay**: Callback schedule delay in us
### cyclictest_wake-up_latency results
Uses cyclictest from the rt-tests test suite to measure wake-up latency. A real-time thread is run on CPU1, and wakes up at a regular interval (specified by the interval parameter) using clock_nanosleep. It then uses clock_gettime and computes the difference between the scheduled wake-up time and the effective wake-up time measured by clock_gettime.
The command used is: cyclictest -p `prio` -a1 -t1 -n -h 200 -q -i `interval`
**Common test metadata:** Task priority: 98, Interval: 200us, Boot Parameters: isolcpus,rcu_nocbs,irqaffinity, ETF qdisc delta: None, Device and processor load: None, qdisc: pfifo_fast, XDP: no
Metadata | Minimum | Maximum | Average | Standard deviation | Lost packets
---------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------
**dev, ker, duration** | **Wake-up latency** | **Wake-up latency** | **Wake-up latency** | **Wake-up latency** |
Shuttle, 4.19, 16h35 | 1.0us | 14.0us | 1.0us | 0.1us | 0
A20, 5.6, 18h13 | 8.0us | 73.0us | 9.3us | 1.5us | 0
![alt text](measures/graphs/cyclictest_wake-up_latencyWake-up latency.png "cyclictest_wake-up_latency Graph")
### ping_interval results
ping measures with command `taskset 2 chrt -f 98 ping -i 0.001 -q IP`
**Common test metadata:** Linux kernel version: 5.6, Task priority: 98, Interval: 1000us, Boot Parameters: isolcpus,rcu_nocbs,irqaffinity, ETF qdisc delta: None, Device and processor load: None, Speed (Mb/s): 1000, Packet route: E2E, XDP: no
Metadata | Minimum | Maximum | Average | Standard deviation | Lost packets
---------------------------- | ------------ | ------------ | ------------ | ------------------ | ------------
**duration, client, server** | **ping RTT** | **ping RTT** | **ping RTT** | **ping RTT** |
0h37, Shuttle, A20 | 59.0us | 460.0us | 272.0us | 74.0us | 0
0h13, A20, Shuttle | 77.0us | 569.0us | 293.0us | 45.0us | 0
![alt text](measures/graphs/ping_intervalping RTT.png "ping_interval Graph")
### shuttle_a20_signal_jitter results
Two A20 boards are connected end to end with an ethernet cable to a shuttle. All devices are synchronized with PTP. The shuttle sends packets containing timestamps to the boards, and the boards emit a signal at the given timestamp. A logic analyzer measures the variation difference between the signals of the two boards.
**Common test metadata:** Device: A20, Linux kernel version: 5.6, Task priority: 98, Boot Parameters: isolcpus,rcu_nocbs,irqaffinity, ETF qdisc delta: None, Device and processor load: None, Speed (Mb/s): 1000, ETF offset: 500us, Packet route: E2E, qdisc: pfifo_fast
Metadata | Minimum | Maximum | Average | Standard deviation | Lost packets
--------------------------- | ------------------------- | ------------------------- | ------------------------- | ------------------------- | ------------
**i, duration, delay, XDP** | **edge to edge - period** | **edge to edge - period** | **edge to edge - period** | **edge to edge - period** |
1000us, 9h59, 600us, no | 0.0us - 958.0us | 129.0us - 1063.0us | 7.5us - 999.5us | 9.6us - 1.8us | 0
500us, 13h59, 400us, no | 0.0us - 360.0us | 265.0us - 582.0us | 10.6us - 499.5us | 9.8us - 1.4us | 0
500us, 14h59, 350us, yes | 0.0us - 443.0us | 101.0us - 558.0us | 9.4us - 499.5us | 8.2us - 1.1us | 0
300us, 1h13, 250us, yes | 0.0us - 251.0us | 84.0us - 352.0us | 8.4us - 299.5us | 6.9us - 2.0us | 0
![alt text](measures/graphs/shuttle_a20_signal_jitteredge to edge.png "shuttle_a20_signal_jitter Graph")
![alt text](measures/graphs/shuttle_a20_signal_jitterperiod.png "shuttle_a20_signal_jitter Graph")
### packet_jitter results
A UDP packet is periodically sent from one device to another using a real time thread. The receiving device calculates the intervals between the packets it receives, and sees how much it differs from the scheduled interval.
**Common test metadata:** Linux kernel version: 5.6, Task priority: 98, Interval: 500us, Boot Parameters: isolcpus,rcu_nocbs,irqaffinity, ETF qdisc delta: None, Device and processor load: None, Speed (Mb/s): 1000, ETF offset: 500us, Packet route: E2E, qdisc: pfifo_fast, Client device: Shuttle, Server device: A20, Callback delay: none
Metadata | Minimum | Maximum | Average | Standard deviation | Lost packets
----------------- | ----------------- | ----------------- | ----------------- | ------------------ | ------------
**duration, XDP** | **Packet jitter** | **Packet jitter** | **Packet jitter** | **Packet jitter** |
0h21, no | 0.0us | 257.0us | 114.5us | 4.0us | 0
0h22, no | 0.0us | 272.0us | 115.5us | 7.3us | 0
0h30, yes | 0.0us | 176.0us | 79.5us | 2.3us | 0
0h30, yes | 0.0us | 234.0us | 106.5us | 8.3us | 0
![alt text](measures/graphs/packet_jitterPacket jitter.png "packet_jitter Graph")
### packet_latency results
Same setup as packet jitter measures. Client and server are synchronized with PTP, the client checks the time before sending the packet, and sends it in the packet. The servechecks the time after receiving the packet, and records the difference between both timestamps to calculate latency.
**Common test metadata:** Linux kernel version: 5.6, Task priority: 98, Boot Parameters: isolcpus,rcu_nocbs,irqaffinity, ETF qdisc delta: None, Device and processor load: None, Speed (Mb/s): 1000, ETF offset: 500us, Packet route: E2E, qdisc: pfifo_fast, Callback delay: none
Metadata | Minimum | Maximum | Average | Standard deviation | Lost packets
------------------------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------
**duration, XDP, i, client, server** | **Packet latency** | **Packet latency** | **Packet latency** | **Packet latency** |
29h26, yes, 500us, Shuttle, A20 | 17.0us | 233.0us | 49.5us | 8.0us | 0
0h59, no, 500us, Shuttle, A20 | 67.0us | 493.0us | 122.7us | 20.7us | 0
0h59, no, 500us, Shuttle, A20 | 69.0us | 519.0us | 124.7us | 21.7us | 0
15h39, no, 1000us, A20, Shuttle | 97.0us | 425.0us | 109.9us | 10.1us | 0
![alt text](measures/graphs/packet_latencyPacket latency.png "packet_latency Graph")
## Additional measures
## Packet transmission latency
### Shuttle to A20
#### Measures done with tracing and timestamps (some overhead):
**Without XDP:**
| **Latency measured** | **min** | **avg** | **max** |
| -------------------------------------- | ------- | ------- | ------- |
| IRQ -> RX SO_TIMESTAMP | 27us | 31us | 136us |
| RX SO_TIMESTAMP -> Userspace timestamp | 85us | 93us | 247us |
| IRQ -> Userspace timestamp | 112us | 124us | 383us |
**With XDP:**
IRQ -> XDP_REDIRECT : ~30us (more measures needs to be done)
#### Measures done with timestamps (little overhead):
| **Latency measured** | | **Duration** | **Packets number** | **Interval** | **min** | **avg** | **max** |
| -------------------------------------- | ------ | ------------ | ------------------ | ------------ | ------- | ------ | ------ |
| Shuttle timestamp -> A20 timestamp | XDP | 2h45 | 50 100 000 | 250us | 22us | 24us | 173us |
| Shuttle timestamp -> A20 timestamp | no XDP | | | | 88us | 88us | 300us |
| RX SO_TIMESTAMP (A20) | no XDP | | | | 67us | 172us | 173us |
| TX SO_TIMESTAMP -> (Shuttle) | no XDP | | | | 2us | 18us | 20us |
#### PTP path delay and master offset
| **Measure** | **min** | **avg** | **max** |
| ---------------------| ------- | ------- | ------- |
| Master offset | -42us | 0us | 71us |
| Path delay | 23us | 31us | 47us |
{"measure_sets": [{"measure_type": "cyclictest_wake-up_latency", "props_names": ["Wake-up latency"], "units": ["us"], "middle": 0, "props": [[0, 296668951, 1253067, 600224, 1797, 141, 49, 10, 7, 6, 5, 1, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], "props_type": "histogram", "metadata": {"dev": "Shuttle", "ker": "4.19", "prio": "98", "i": "200us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "16h35", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "A20", "server": "A20", "XDP": "no", "delay": "none", "lost_packets": "0"}}]}
\ No newline at end of file
{"measure_sets": [{"measure_type": "cyclictest_wake-up_latency", "props_names": ["Wake-up latency"], "units": ["us"], "middle": 0, "props": [[0, 0, 0, 0, 0, 0, 0, 0, 19708967, 290863204, 843353, 116187, 57711, 55555, 143818, 10818251, 4130587, 1281816, 69168, 24688, 11616, 5276, 3337, 2511, 2031, 1507, 1364, 1201, 1116, 1064, 937, 841, 654, 568, 515, 588, 762, 762, 735, 617, 537, 391, 277, 188, 156, 108, 105, 73, 43, 40, 33, 20, 10, 13, 14, 9, 8, 6, 2, 7, 8, 7, 5, 2, 5, 2, 1, 1, 2, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], "props_type": "histogram", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "200us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "18h13", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "A20", "server": "A20", "XDP": "no", "delay": "none", "lost_packets": "0"}}]}
\ No newline at end of file
{"cyclictest_wake-up_latency": {"ids": [3, 5], "next_id": 6}, "ping_interval": {"ids": [0, 1], "next_id": 2}, "shuttle_a20_signal_jitter": {"ids": [4, 7, 8, 9], "next_id": 10}, "packet_jitter": {"ids": [0, 1, 2, 3], "next_id": 4}, "packet_latency": {"ids": [0, 1, 2, 3], "next_id": 4}}
\ No newline at end of file
{"measure_sets": [{"measure_type": "packet_jitter", "props_names": ["Packet jitter"], "units": ["us"], "middle": 0, "props": [[1, 0, 0, 0, 0, 2, 0, 0, 1, 1, 1, 1, 5, 3, 2, 3, 3, 1, 6, 2, 5, 8, 6, 4, 4, 8, 8, 8, 9, 12, 5, 10, 7, 5, 5, 8, 9, 11, 15, 20, 13, 9, 26, 19, 21, 28, 28, 29, 36, 38, 31, 34, 46, 49, 58, 59, 49, 47, 81, 58, 65, 79, 89, 91, 88, 76, 76, 95, 93, 82, 91, 113, 128, 113, 131, 103, 106, 113, 160, 115, 121, 145, 159, 177, 180, 207, 213, 288, 294, 349, 408, 441, 527, 513, 575, 612, 625, 629, 676, 688, 792, 927, 990, 1295, 1657, 2046, 2687, 3364, 4770, 6753, 11331, 25253, 97215, 393241, 811289, 752549, 344312, 96192, 25644, 9252, 5392, 3939, 3139, 2508, 2139, 1735, 1471, 1277, 1130, 918, 802, 715, 598, 536, 499, 451, 396, 369, 318, 305, 268, 267, 271, 289, 324, 318, 341, 314, 255, 263, 208, 164, 169, 167, 131, 119, 119, 131, 108, 90, 111, 134, 122, 124, 105, 121, 100, 108, 81, 90, 93, 84, 78, 80, 92, 82, 65, 63, 57, 63, 61, 63, 62, 66, 71, 70, 75, 60, 54, 68, 42, 54, 42, 54, 40, 38, 34, 26, 42, 38, 28, 18, 18, 18, 25, 13, 16, 20, 16, 11, 9, 13, 13, 13, 7, 2, 5, 6, 3, 7, 7, 6, 3, 9, 8, 8, 7, 4, 1, 7, 11, 3, 5, 2, 5, 8, 4, 2, 3, 2, 2, 0, 2, 3, 4, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1]], "props_type": "histogram", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "500us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "0h21", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "Shuttle", "server": "A20", "XDP": "no", "delay": "none", "lost_packets": "0"}}]}
{"measure_sets": [{"measure_type": "packet_jitter", "props_names": ["Packet jitter"], "units": ["us"], "middle": 0, "props": [[1, 0, 0, 0, 1, 1, 0, 0, 3, 3, 3, 4, 1, 2, 2, 6, 0, 2, 2, 3, 4, 4, 7, 4, 6, 6, 11, 7, 10, 10, 8, 10, 6, 9, 8, 4, 8, 21, 18, 11, 18, 15, 25, 12, 24, 27, 25, 33, 34, 50, 41, 71, 60, 57, 98, 75, 88, 97, 99, 124, 137, 161, 152, 179, 167, 191, 181, 198, 222, 208, 227, 228, 277, 256, 244, 266, 318, 341, 339, 370, 412, 419, 450, 500, 504, 517, 550, 610, 667, 789, 850, 1151, 1524, 2553, 4432, 7661, 11184, 12444, 10487, 7869, 6907, 7052, 8043, 9627, 11381, 13489, 14994, 17491, 22842, 30546, 40433, 47746, 54603, 102806, 327406, 656063, 580035, 227440, 53692, 31574, 35150, 37261, 32996, 25710, 19435, 15332, 13363, 12405, 10314, 8612, 7438, 7009, 6800, 7580, 10148, 12054, 10556, 7245, 4486, 2922, 2017, 1572, 1195, 1057, 915, 815, 761, 699, 657, 619, 497, 474, 422, 374, 318, 302, 306, 264, 245, 278, 241, 235, 265, 222, 268, 262, 263, 268, 243, 239, 231, 218, 167, 205, 174, 176, 169, 144, 159, 154, 127, 144, 112, 128, 118, 117, 90, 119, 73, 91, 75, 84, 67, 57, 55, 52, 45, 39, 25, 26, 36, 32, 16, 18, 23, 15, 18, 14, 8, 6, 8, 9, 9, 8, 3, 6, 7, 7, 5, 3, 1, 7, 4, 1, 2, 4, 3, 4, 5, 5, 1, 3, 1, 1, 0, 1, 1, 2, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]], "props_type": "histogram", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "500us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "0h22", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "Shuttle", "server": "A20", "XDP": "no", "delay": "none", "lost_packets": "0"}}]}
{"measure_sets": [{"measure_type": "packet_jitter", "props_names": ["Packet jitter"], "units": ["us"], "middle": 0, "props": [[1, 0, 0, 0, 1, 1, 2, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, 1, 1, 1, 2, 0, 3, 5, 1, 1, 2, 4, 5, 4, 3, 1, 2, 3, 6, 4, 3, 14, 14, 16, 14, 18, 29, 39, 44, 64, 61, 68, 86, 116, 144, 153, 183, 219, 244, 229, 304, 345, 377, 448, 503, 625, 678, 819, 933, 1050, 1097, 1260, 1355, 1512, 1623, 1971, 2598, 3719, 6072, 10102, 19029, 73457, 463223, 1266922, 1160009, 444611, 76203, 17385, 10051, 6331, 4209, 3212, 2477, 1859, 1391, 1160, 1085, 990, 932, 862, 814, 740, 706, 580, 501, 436, 382, 315, 280, 260, 279, 263, 222, 193, 188, 179, 159, 116, 103, 103, 88, 73, 83, 94, 66, 68, 62, 74, 69, 64, 59, 44, 56, 49, 64, 42, 43, 50, 30, 32, 23, 20, 20, 20, 9, 14, 7, 4, 5, 9, 8, 3, 7, 8, 4, 3, 3, 5, 4, 2, 2, 3, 0, 1, 2, 5, 2, 2, 5, 1, 2, 3, 3, 3, 2, 1, 0, 1, 0, 0, 1]], "props_type": "histogram", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "500us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "0h30", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "Shuttle", "server": "A20", "XDP": "yes", "delay": "none", "lost_packets": "0"}}]}
{"measure_sets": [{"measure_type": "packet_jitter", "props_names": ["Packet jitter"], "units": ["us"], "middle": 0, "props": [[1, 0, 0, 0, 0, 0, 1, 0, 1, 2, 2, 4, 0, 4, 3, 5, 1, 6, 4, 4, 6, 5, 5, 8, 14, 11, 10, 10, 15, 15, 19, 24, 26, 30, 36, 29, 30, 38, 42, 38, 31, 50, 61, 47, 61, 64, 76, 76, 92, 88, 110, 114, 131, 163, 156, 180, 169, 195, 200, 171, 179, 163, 179, 143, 129, 116, 140, 144, 153, 166, 200, 216, 244, 240, 333, 374, 424, 557, 693, 811, 1047, 1277, 1526, 1794, 2196, 3028, 4795, 9855, 23525, 46501, 59834, 58186, 57548, 43361, 26434, 14805, 13785, 27054, 35587, 20331, 7719, 5843, 7773, 15101, 59734, 377211, 1022522, 883792, 266431, 29246, 4190, 1873, 1365, 1722, 7545, 27493, 32307, 18479, 11694, 18995, 34560, 50745, 54952, 51461, 53546, 39244, 19386, 8853, 4873, 3375, 2832, 2441, 2079, 1722, 1469, 1278, 1107, 869, 766, 615, 486, 438, 388, 391, 344, 344, 319, 281, 258, 238, 199, 216, 186, 208, 188, 189, 179, 169, 229, 216, 265, 218, 227, 220, 218, 176, 151, 112, 121, 114, 78, 73, 62, 35, 46, 38, 47, 39, 41, 21, 30, 39, 30, 19, 21, 14, 19, 13, 12, 21, 11, 16, 16, 8, 10, 10, 9, 3, 4, 7, 4, 3, 2, 4, 2, 2, 1, 3, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1]], "props_type": "histogram", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "500us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "0h30", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "Shuttle", "server": "A20", "XDP": "yes", "delay": "none", "lost_packets": "0"}}]}
{"measure_sets": [{"measure_type": "packet_latency", "props_names": ["Packet latency"], "units": ["us"], "middle": 0, "props": [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 58, 2270, 12012, 23545, 36633, 77703, 150473, 235651, 345515, 506772, 724939, 999772, 1317172, 1750377, 2277722, 2831677, 3311876, 3579594, 3615450, 3601367, 3558365, 3469742, 3421680, 3411272, 3432516, 3577532, 3960194, 4465113, 5249020, 6379391, 7751402, 10178992, 14579740, 20178918, 25548634, 26659032, 20154219, 10589803, 4483218, 1865194, 826784, 425360, 267225, 175096, 124218, 96349, 77623, 65898, 57834, 50589, 44464, 40012, 38414, 36002, 33756, 31581, 30159, 29185, 28666, 28500, 29385, 29844, 30996, 32383, 33571, 34476, 35594, 35893, 36111, 36411, 35843, 35604, 35331, 35050, 34643, 34445, 34996, 35647, 36617, 37590, 38136, 38216, 37158, 35422, 33420, 30229, 26401, 22709, 18811, 16059, 13365, 10951, 8987, 7449, 6411, 5270, 4501, 3848, 3344, 2911, 2803, 2693, 2804, 2835, 2846, 3048, 3368, 3638, 4066, 4094, 4002, 3798, 3457, 3201, 3133, 3175, 3364, 3364, 3596, 3723, 3543, 3546, 3425, 3281, 2976, 2479, 2045, 1577, 1141, 897, 588, 436, 317, 242, 217, 137, 131, 91, 100, 73, 75, 80, 46, 44, 38, 33, 39, 38, 44, 20, 28, 28, 31, 20, 22, 22, 10, 13, 11, 15, 13, 11, 6, 7, 6, 5, 7, 4, 4, 1, 6, 4, 2, 4, 3, 2, 1, 2, 2, 0, 2, 5, 2, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 4, 0, 0, 1, 0, 1, 0, 1, 0, 1, 2, 0, 1]], "props_type": "histogram", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "500us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "29h26", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "Shuttle", "server": "A20", "XDP": "yes", "delay": "none", "lost_packets": "0"}}]}
{"measure_sets": [{"measure_type": "packet_latency", "props_names": ["Packet latency"], "units": ["us"], "middle": 0, "props": [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 15, 25, 30, 45, 60, 75, 73, 89, 99, 93, 126, 126, 219, 361, 434, 643, 857, 1181, 1576, 1947, 2532, 2872, 3422, 3852, 4051, 4263, 4323, 4272, 4407, 4379, 4331, 4456, 4418, 4661, 5001, 5674, 6518, 7994, 11162, 17551, 29098, 50693, 97340, 206157, 399670, 597135, 699487, 726710, 693149, 600635, 482208, 371829, 282923, 218711, 169608, 133859, 108160, 90633, 76832, 64821, 55787, 47522, 40591, 34946, 30064, 26276, 23612, 21217, 19811, 19114, 18533, 18172, 18000, 17269, 16874, 16612, 16503, 16328, 16418, 16171, 16286, 15983, 15203, 14138, 13596, 12485, 11669, 11249, 10628, 10651, 10720, 10483, 10570, 10500, 10379, 9904, 9594, 8605, 7774, 6851, 5993, 5315, 4588, 4012, 3397, 2996, 2562, 2393, 2177, 1960, 1818, 1573, 1386, 1321, 1152, 1001, 945, 853, 848, 769, 686, 690, 676, 623, 576, 615, 616, 588, 562, 570, 648, 590, 636, 620, 615, 625, 648, 663, 675, 693, 732, 722, 741, 758, 741, 798, 806, 849, 901, 926, 985, 1019, 1118, 1258, 1265, 1371, 1341, 1368, 1360, 1228, 1223, 1259, 1271, 1297, 1451, 1749, 1887, 2158, 2491, 2798, 3154, 3340, 3816, 4029, 4425, 4572, 4731, 4778, 4845, 4639, 4459, 4211, 3873, 3500, 3020, 2655, 2367, 2026, 1915, 1726, 1741, 1718, 1791, 1824, 1746, 1712, 1709, 1581, 1380, 1251, 1131, 961, 882, 801, 701, 666, 632, 590, 565, 484, 481, 432, 401, 306, 287, 271, 191, 186, 155, 127, 106, 73, 68, 48, 46, 41, 25, 31, 26, 36, 33, 32, 40, 24, 28, 31, 37, 31, 23, 29, 28, 24, 37, 27, 22, 26, 27, 31, 24, 24, 26, 16, 12, 16, 16, 10, 15, 10, 13, 10, 15, 8, 7, 6, 11, 10, 11, 10, 7, 6, 11, 5, 5, 9, 8, 5, 4, 7, 4, 2, 5, 9, 11, 6, 6, 5, 4, 2, 3, 3, 4, 5, 0, 4, 4, 1, 2, 2, 0, 0, 0, 1, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]], "props_type": "histogram", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "500us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "0h59", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "Shuttle", "server": "A20", "XDP": "no", "delay": "none", "lost_packets": "0"}}]}
{"measure_sets": [{"measure_type": "packet_latency", "props_names": ["Packet latency"], "units": ["us"], "middle": 0, "props": [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 11, 23, 26, 34, 32, 58, 63, 91, 90, 121, 181, 222, 263, 315, 450, 563, 911, 1235, 1721, 2269, 2742, 3218, 3519, 3700, 4154, 4262, 4336, 4399, 4396, 4317, 4646, 4916, 4944, 5655, 6161, 6959, 8257, 9669, 12626, 18908, 30377, 52510, 98730, 200748, 385913, 587771, 702210, 733646, 708278, 620331, 496700, 374801, 278483, 210554, 160757, 125586, 100569, 82806, 70174, 60261, 52510, 46054, 40846, 35661, 32035, 28386, 25484, 23115, 21164, 20305, 19237, 18756, 17983, 18028, 17633, 17604, 17521, 17786, 17612, 17412, 17277, 16560, 15598, 14582, 13451, 12571, 11610, 11209, 10660, 10213, 10219, 10100, 9954, 9619, 9274, 8497, 7697, 6987, 6221, 5740, 4952, 4462, 4243, 3677, 3464, 3138, 2889, 2729, 2629, 2318, 2258, 2106, 1789, 1697, 1462, 1207, 1145, 936, 810, 763, 667, 654, 588, 606, 649, 612, 601, 663, 647, 675, 711, 728, 736, 780, 816, 825, 887, 939, 991, 1079, 1098, 1200, 1202, 1174, 1197, 1126, 1046, 984, 939, 882, 833, 831, 835, 808, 747, 704, 728, 764, 738, 762, 943, 1039, 1126, 1464, 1638, 1962, 2234, 2577, 2860, 3216, 3554, 3726, 4030, 4133, 4167, 4037, 4024, 3758, 3743, 3637, 3345, 3172, 2921, 2667, 1573, 1051, 924, 787, 739, 714, 676, 694, 678, 784, 806, 832, 857, 934, 856, 874, 817, 820, 716, 686, 600, 535, 457, 472, 414, 487, 514, 514, 425, 392, 328, 250, 217, 227, 212, 247, 275, 303, 421, 478, 560, 681, 778, 873, 1016, 1117, 1056, 1134, 1128, 1149, 1068, 944, 859, 814, 697, 674, 569, 526, 451, 425, 387, 362, 345, 339, 291, 308, 324, 240, 247, 209, 224, 157, 122, 113, 80, 67, 46, 40, 32, 29, 30, 23, 24, 16, 10, 13, 21, 13, 13, 11, 8, 12, 11, 10, 13, 16, 6, 20, 16, 17, 15, 12, 17, 19, 14, 12, 12, 11, 14, 15, 17, 18, 6, 8, 7, 6, 10, 3, 7, 4, 4, 11, 6, 9, 4, 5, 10, 5, 12, 5, 7, 13, 6, 12, 15, 7, 12, 8, 8, 10, 8, 10, 13, 5, 4, 9, 7, 4, 11, 4, 6, 2, 6, 6, 6, 6, 4, 8, 7, 3, 5, 5, 3, 2, 3, 3, 1, 0, 1, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1]], "props_type": "histogram", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "500us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "0h59", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "Shuttle", "server": "A20", "XDP": "no", "delay": "none", "lost_packets": "0"}}]}
{"measure_sets": [{"measure_type": "packet_latency", "props_names": ["Packet latency"], "units": ["us"], "middle": 0, "props": [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 1716, 10071, 56372, 394307, 1778145, 4697809, 6846774, 7330990, 6607488, 5311777, 3859053, 2862080, 2018545, 1586170, 1233933, 934580, 764396, 658843, 597718, 554044, 534873, 497445, 493398, 489767, 466660, 471787, 490805, 506679, 525088, 534342, 483884, 444454, 390179, 316198, 263053, 215024, 167955, 129064, 95841, 69513, 51791, 38123, 29081, 22733, 18885, 17144, 15164, 13633, 12471, 11409, 10355, 9721, 9130, 8682, 8481, 8192, 7674, 7245, 6831, 6452, 6117, 5748, 5556, 5548, 5331, 5062, 5105, 5142, 5202, 5290, 5554, 5830, 6476, 6688, 6937, 7163, 7152, 7520, 7285, 7141, 7547, 7788, 7721, 8304, 8309, 8161, 8639, 8470, 8620, 9046, 9292, 9626, 10051, 9542, 9524, 9412, 8898, 8466, 8190, 7576, 7003, 6546, 5634, 5089, 4647, 3903, 3519, 3269, 3046, 2863, 2581, 2289, 2131, 1906, 1743, 1629, 1625, 1552, 1448, 1366, 1233, 1156, 1012, 945, 872, 870, 728, 687, 626, 546, 495, 432, 434, 365, 330, 295, 292, 245, 208, 193, 197, 191, 171, 194, 150, 172, 143, 148, 156, 132, 150, 162, 154, 137, 164, 136, 139, 141, 152, 135, 144, 146, 131, 132, 135, 126, 133, 142, 135, 124, 114, 144, 115, 108, 117, 92, 108, 121, 85, 92, 86, 67, 74, 92, 85, 85, 72, 60, 52, 50, 61, 44, 53, 41, 45, 45, 36, 33, 32, 30, 19, 24, 24, 26, 22, 25, 25, 23, 10, 15, 13, 12, 7, 6, 5, 8, 4, 1, 2, 8, 0, 1, 2, 3, 0, 2, 4, 3, 3, 2, 4, 2, 1, 2, 3, 1, 2, 0, 2, 3, 3, 3, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 2, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]], "props_type": "histogram", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "1000us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "15h39", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "A20", "server": "Shuttle", "XDP": "no", "delay": "none", "lost_packets": "0"}}]}
\ No newline at end of file
{"measure_sets": [{"measure_type": "ping_interval", "props_names": ["ping RTT"], "units": ["us"], "middle": 0, "props": [[59, 460, 272, 74, "2271655"]], "props_type": "minmaxavg", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "1000us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "0h37", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "Shuttle", "server": "A20", "XDP": "no", "delay": "none", "lost_packets": "0"}}]}
{"measure_sets": [{"measure_type": "ping_interval", "props_names": ["ping RTT"], "units": ["us"], "middle": 0, "props": [[77, 569, 293, 45, "827098"]], "props_type": "minmaxavg", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "1000us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "0h13", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "A20", "server": "Shuttle", "XDP": "no", "delay": "none", "lost_packets": "0"}}]}
\ No newline at end of file
{"measure_sets": [{"measure_type": "shuttle_a20_signal_jitter", "props_names": ["edge to edge", "period"], "units": ["us", "us"], "middle": 0, "props": [[5734257, 5168042, 4043516, 3067680, 2379201, 1939009, 1599983, 1290702, 1023491, 784965, 617117, 509686, 439411, 399061, 370748, 352073, 343861, 331345, 324823, 324024, 321931, 324863, 328791, 325885, 325305, 326105, 327722, 328588, 315892, 293577, 266053, 242344, 220569, 187493, 149460, 115307, 87105, 67892, 55554, 45284, 39381, 37255, 35949, 34565, 30062, 26305, 22937, 19780, 14405, 9310, 6457, 5410, 3749, 2380, 1741, 1472, 1301, 987, 884, 735, 654, 605, 431, 358, 256, 249, 212, 162, 153, 159, 128, 123, 132, 128, 116, 134, 138, 111, 91, 85, 63, 67, 62, 51, 56, 53, 64, 60, 66, 71, 64, 62, 45, 42, 46, 47, 26, 31, 20, 13, 20, 8, 7, 6, 7, 2, 5, 1, 1, 1, 0, 1, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 3, 0, 4, 8, 5, 8, 14, 21, 48, 61, 130, 327, 604, 1177, 2296, 3707, 5521, 7277, 9237, 11097, 12664, 14027, 16046, 18066, 20954, 24104, 27785, 32427, 39279, 49325, 67863, 107059, 289808, 1779306, 8960078, 24761891, 23504503, 8604311, 2632300, 485641, 115137, 53905, 36299, 33121, 32423, 27634, 22168, 17234, 15448, 15184, 15076, 13919, 12576, 10341, 8213, 7177, 6724, 7153, 7937, 8866, 8936, 8787, 7570, 6110, 4346, 3072, 1901, 1128, 655, 282, 150, 65, 15, 7, 3, 2, 2, 1, 2, 0, 2, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1]], "props_type": "histogram", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "1000us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "9h59", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "A20", "server": "A20", "XDP": "no", "delay": "600us", "lost_packets": "0"}}]}
{"measure_sets": [{"measure_type": "shuttle_a20_signal_jitter", "props_names": ["edge to edge", "period"], "units": ["us", "us"], "middle": 0, "props": [[8257327, 8344463, 7783391, 7096625, 6390296, 5606943, 4787888, 4015736, 3445982, 2970116, 2632229, 2409304, 2227238, 2100931, 2004104, 1931109, 1894616, 1844486, 1819007, 1823767, 1835950, 1861141, 1864219, 1821236, 1766006, 1680005, 1576069, 1474049, 1341584, 1204611, 1031396, 839412, 669063, 521573, 413333, 337240, 262190, 202881, 159270, 120056, 90984, 72949, 57979, 44693, 34459, 29228, 22015, 14955, 11022, 8229, 6937, 5842, 4890, 4178, 3542, 2912, 2459, 2065, 1713, 1567, 1245, 1046, 868, 721, 542, 470, 367, 363, 295, 310, 273, 250, 237, 214, 177, 176, 149, 146, 101, 102, 87, 75, 65, 68, 49, 46, 38, 24, 13, 9, 9, 9, 5, 3, 1, 1, 2, 1, 0, 2, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 2, 2, 1, 3, 1, 1, 2, 3, 2, 0, 1, 1, 1, 1, 4, 2, 1, 1, 0, 0, 2, 1, 1, 2, 0, 0, 2, 0, 2, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 2, 0, 1, 1, 1, 2, 0, 0, 1, 1, 2, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 2, 1, 0, 0, 0, 2, 1, 0, 0, 0, 2, 1, 3, 1, 2, 3, 13, 11, 11, 24, 33, 74, 185, 479, 1070, 2199, 4466, 8154, 13666, 21172, 30250, 39533, 50179, 60433, 72876, 88899, 116008, 164434, 252430, 565979, 3236242, 22631054, 74263646, 70869460, 21897374, 4903234, 1105684, 340153, 182846, 120568, 94506, 77580, 59425, 42956, 33425, 30451, 30304, 30854, 29994, 28051, 24388, 20575, 16479, 12702, 8922, 5744, 3269, 1865, 951, 454, 220, 89, 31, 20, 12, 6, 8, 10, 8, 3, 4, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1]], "props_type": "histogram", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "500us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "13h59", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "A20", "server": "A20", "XDP": "no", "delay": "400us", "lost_packets": "0"}}]}
{"measure_sets": [{"measure_type": "shuttle_a20_signal_jitter", "props_names": ["edge to edge", "period"], "units": ["us", "us"], "middle": 0, "props": [[8183287, 8424771, 8039602, 7451076, 6909046, 6429988, 5822968, 5261034, 4812280, 4275843, 3766005, 3416967, 3060235, 2777081, 2547466, 2392726, 2308681, 2226862, 2131337, 2047233, 1956650, 1880294, 1789020, 1645838, 1497282, 1354765, 1211021, 1020612, 836823, 657940, 497613, 403454, 311115, 207959, 132939, 91715, 57421, 33984, 21288, 15864, 11283, 9495, 8431, 7664, 6721, 6093, 5210, 4337, 3616, 2956, 2495, 2020, 1548, 1291, 1190, 1060, 773, 722, 636, 684, 657, 616, 649, 666, 624, 690, 714, 712, 696, 649, 633, 649, 590, 561, 561, 520, 465, 358, 125, 98, 59, 42, 26, 19, 17, 11, 10, 8, 2, 6, 4, 4, 3, 3, 1, 1, 2, 0, 1, 0, 0, 2], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3, 4, 6, 10, 12, 19, 36, 42, 70, 62, 111, 142, 214, 330, 759, 1689, 3696, 7486, 13949, 22731, 33733, 47174, 59458, 70929, 81599, 94937, 118997, 169090, 286583, 780808, 10670257, 94090623, 93837861, 12875708, 1580087, 328125, 179817, 119407, 85386, 62917, 48345, 40900, 37694, 36661, 34840, 32270, 29441, 26112, 23551, 20074, 15799, 11017, 6675, 3560, 1742, 756, 363, 227, 154, 113, 100, 67, 62, 47, 26, 17, 11, 5, 10, 2, 3, 0, 2, 3, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1]], "props_type": "histogram", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "500us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "14h59", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "A20", "server": "A20", "XDP": "yes", "delay": "350us", "lost_packets": "0"}}]}
{"measure_sets": [{"measure_type": "shuttle_a20_signal_jitter", "props_names": ["edge to edge", "period"], "units": ["us", "us"], "middle": 0, "props": [[1057533, 1047206, 1058072, 1037666, 1024925, 967503, 928475, 835906, 780879, 714538, 656200, 594601, 546354, 477986, 414040, 363333, 336232, 297891, 274893, 230815, 206248, 187233, 156432, 129737, 116426, 87318, 59470, 47696, 32153, 22255, 16242, 12715, 10013, 7847, 8984, 8334, 6711, 6304, 5887, 4846, 3706, 3492, 2862, 2580, 2243, 1925, 1244, 979, 736, 446, 277, 223, 188, 155, 123, 94, 70, 51, 46, 37, 33, 21, 19, 17, 18, 12, 6, 7, 5, 3, 13, 5, 2, 3, 1, 4, 1, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 9, 7, 7, 10, 17, 22, 39, 37, 55, 52, 73, 128, 150, 262, 281, 360, 358, 396, 354, 397, 480, 576, 779, 853, 1066, 1452, 1967, 3149, 4429, 10993, 28347, 25890, 13038, 40189, 107324, 58595, 13690, 9630, 10516, 19706, 25115, 28139, 79857, 1273691, 13172953, 12514086, 1500499, 220389, 35943, 24274, 17714, 10549, 8887, 9466, 13352, 88439, 97556, 22631, 12089, 32686, 25280, 8400, 4035, 3263, 2685, 1963, 1482, 1201, 1049, 849, 807, 724, 528, 410, 325, 304, 354, 320, 306, 276, 216, 153, 69, 34, 18, 10, 13, 2, 4, 1, 2, 0, 2, 0, 0, 1, 0, 2]], "props_type": "histogram", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "300us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "1h13", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "A20", "server": "A20", "XDP": "yes", "delay": "250us", "lost_packets": "0"}}]}
#Report description
This report was generated with the measure-analysis.py script.
JSON formated measures were imported in the measures folder using the import functionnality of the script, this report was then generated using these measures.
Metadata is included with the measures, such as the kernel version used, the boot parameters passed, various others parameters specific to the measure, etc...
Measures measuring the same propriety are grouped together in tables and graphs, and are identified by their diverging metadatas. This is useful to analyse the effect of specific parameters on the measured propriety.
#Metadata
##dev
Default value: A20
Short name: Device
Description: Device on which the tests were run
##ker
Default value: 5.6
Short name: Linux kernel version
Description: Linux kernel version used
##prio
Default value: 98
Short name: Task priority
Description: Priority of the real-time thread
##i
Default value: 1000us
Short name: Interval
Description: Interval between each packet transmission
##boot_p
Default value: isolcpus,rcu_nocbs,irqaffinity
Short name: Boot Parameters
Description: Boot Parameters passed to u-boot
##delta
Default value: None
Short name: ETF qdisc delta
Description: ETF qdisc delta value
##load
Default value: None
Short name: Device and processor load
Description: External device and processor load during the test
##duration
Default value: 0h00
Short name: Test duration
Description: Duration of the test
##speed
Default value: 1000
Short name: Speed (Mb/s)
Description: Ethernet speed in Mb/s
##etf_offset
Default value: 500us
Short name: ETF offset
Description: When a packet\s txtime is scheduled, the txtime set is the current time offset by etf_offset
##route
Default value: E2E
Short name: Packet route
Description: How the boards are connected. switch means they are connected by a switch (cheap, unmanaged), E2E
##qdisc
Default value: pfifo_fast
Short name: qdisc
Description: qdisc used to send packets
##client
Default value: Shuttle
Short name: Client device
Description: Device which sent the packets
##server
Default value: A20
Short name: Server device
Description: Device which received the packets
##XDP
Default value: no
Short name: XDP
Description: Were XDP sockets used
##delay
Default value: none
Short name: Callback delay
Description: Callback schedule delay in us
#Ignored metadata
#Test types descriptions
##cyclictest_wake-up_latency
Ignored metadata: qdisc,route,speed,etf_offset,delay,client,server,xdp
Description: Uses cyclictest from the rt-tests test suite to measure wake-up latency. A real-time thread is run on CPU1, and wakes up at a regular interval (specified by the interval parameter) using clock_nanosleep. It then uses clock_gettime and computes the difference between the scheduled wake-up time and the effective wake-up time measured by clock_gettime.
The command used is: cyclictest -p `prio` -a1 -t1 -n -h 200 -q -i `interval`
##packet_jitter
Ignored metadata: delay,dev
Description: A UDP packet is periodically sent from one device to another using a real time thread. The receiving device calculates the intervals between the packets it receives, and sees how much it differs from the scheduled interval.
##packet_latency
Ignored metadata: delay,dev
Description: Same setup as packet jitter measures. Client and server are synchronized with PTP, the client checks the time before sending the packet, and sends it in the packet. The servechecks the time after receiving the packet, and records the difference between both timestamps to calculate latency.
##packet_rx_timestamps
Ignored metadata: delay,client,server
Description: An UDP packet is periodically sent from one board to another using a real time thread. The receiving board uses the SO_TIMESTAMPING option to see when the packet entered the kernel, and generates timestamps with clock_gettime once the packets enters userspace to compute the time the packet spent in kernel space.
##packet_tx_timestamps
Ignored metadata: delay,client,server
Description: Similar to packet_rx_timestamps, but on the transmitting board.
##packet_rtt
Ignored metadata: delay,dev
Description: A UDP packet is periodically sent from one board to another and sent back as soon as it arrives using a real time thread. The round trip time is computed with clock_gettime on the transmitting board.
##shuttle_a20_signal_jitter
Ignored metadata: dev,client,server
Description: Two A20 boards are connected end to end with an ethernet cable to a shuttle. All devices are synchronized with PTP. The shuttle sends packets containing timestamps to the boards, and the boards emit a signal at the given timestamp. A logic analyzer measures the variation difference between the signals of the two boards.
##shuttle_signal_jitter
Ignored metadata: delay,client,server,dev
Description: Two shuttles connected end to end with an ethernet cable and synchronized with PTP emit signals, and a logic analyzer measures variation in those signals, similar to "Shuttle controlled A20 signal output jitter" measures
##ping_interval
Ignored metadata: delta,qdisc,etf_offset,delay,dev,xdp
Description: ping measures with command `taskset 2 chrt -f 98 ping -i 0.001 -q IP`
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment