in perfkitbenchmarker/linux_benchmarks/dpdk_pktgen_benchmark.py [0:0]
def Run(benchmark_spec: bm_spec.BenchmarkSpec) -> list[sample.Sample]:
"""Runs DPDK benchmarks.
Args:
benchmark_spec: The benchmark specification.
Returns:
A list of sample.Sample objects with the performance results.
Raises:
RunError: A run-stage error raised by an individual benchmark.
"""
sender_vm, receiver_vm = benchmark_spec.vms[:2]
samples = []
num_lcores = min(sender_vm.NumCpusForBenchmark(), _MAX_LCORES)
num_memory_channels_stdout, _ = sender_vm.RemoteCommand(
"lscpu | grep 'NUMA node(s)' | awk '{print $3}'"
)
num_memory_channels = int(num_memory_channels_stdout)
metadata = {
'dpdk_pkgen_burst': 1,
'dpdk_pktgen_lcores': num_lcores,
'dpdk_pktgen_num_memory_channels': num_memory_channels,
'dpdk_pktgen_duration': _DPDK_PKTGEN_DURATION.value,
'dpdk_pktgen_num_flows': _DPDK_PKTGEN_NUM_FLOWS.value,
}
pktgen_env_var = ''
# Incorrect llq_policy default:
# https://github.com/amzn/amzn-drivers/issues/331
aws_eal_arg = ''
if sender_vm.CLOUD == 'AWS':
pktgen_env_var = ' LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64'
aws_eal_arg = f' -a "{receiver_vm.secondary_nic_bus_info},llq_policy=1"'
cmd = (
f'cd {dpdk_pktgen.DPDK_PKTGEN_GIT_REPO_DIR} &&'
f' sudo{pktgen_env_var} ./usr/local/bin/pktgen -l 0-{num_lcores-1} -n'
f' {num_memory_channels}{aws_eal_arg} -- -m "[1-7].0" -f pktgen.pkt >'
f' {_STDOUT_LOG_FILE}'
)
prev_rate = _START_RATE
for packet_loss_threshold in _DPDK_PKTGEN_PACKET_LOSS_THRESHOLDS.value:
metadata = metadata.copy()
metadata['dpdk_pktgen_packet_loss_threshold'] = packet_loss_threshold
valid_total_sender_tx_pkts = None
valid_total_sender_rx_pkts = None
valid_total_receiver_rx_pkts = None
valid_packet_loss_rate = 1
# Binary search for max PPS under packet loss rate thresholds.
prev_pps, curr_pps = -float('inf'), 0
lb, ub = 0, _START_RATE * 2
while (
(abs(curr_pps - prev_pps) / (curr_pps + 1))
> _PPS_BINARY_SEARCH_THRESHOLD
) or (not valid_total_receiver_rx_pkts):
curr_rate = (lb + ub) / 2
sender_vm.RemoteCommand(
f'sudo sed -i "s/pps = {prev_rate};/pps ='
f' {curr_rate};/g"'
f' {dpdk_pktgen.DPDK_PKTGEN_GIT_REPO_DIR}/app/pktgen.c'
)
sender_vm.RemoteCommand(
f'cd {dpdk_pktgen.DPDK_PKTGEN_GIT_REPO_DIR} && make'
)
# Running Pktgen requires a terminal.
background_tasks.RunThreaded(
lambda vm: vm.RemoteCommand(
cmd, login_shell=True, disable_tty_lock=True
),
[receiver_vm, sender_vm],
post_task_delay=1, # Ensure receiver starts before sender.
)
# Parse ANSI codes.
stdout_rx_parser = (
f'cat {dpdk_pktgen.DPDK_PKTGEN_GIT_REPO_DIR}/{_STDOUT_LOG_FILE} |'
r' grep -oP "\[7;22H\s*\K[0-9]+" | tail -1'
)
stdout_tx_parser = (
f'cat {dpdk_pktgen.DPDK_PKTGEN_GIT_REPO_DIR}/{_STDOUT_LOG_FILE} |'
r' grep -oP "\[8;22H\s*\K[0-9]+" | tail -1'
)
total_sender_tx_pkts, _ = sender_vm.RemoteCommand(stdout_tx_parser)
total_sender_rx_pkts, _ = sender_vm.RemoteCommand(stdout_rx_parser)
total_receiver_rx_pkts, _ = receiver_vm.RemoteCommand(stdout_rx_parser)
packet_loss_rate = (
int(total_sender_tx_pkts)
+ int(total_sender_rx_pkts)
- int(total_receiver_rx_pkts)
) / int(total_sender_tx_pkts)
if packet_loss_rate > packet_loss_threshold:
ub = curr_rate
else:
valid_total_sender_tx_pkts = total_sender_tx_pkts
valid_total_sender_rx_pkts = total_sender_rx_pkts
valid_total_receiver_rx_pkts = total_receiver_rx_pkts
valid_packet_loss_rate = packet_loss_rate
lb = curr_rate
prev_pps, curr_pps = (
curr_pps,
int(total_receiver_rx_pkts) // _DPDK_PKTGEN_DURATION.value,
)
prev_rate = curr_rate
samples.extend([
sample.Sample(
'Total sender tx packets',
int(valid_total_sender_tx_pkts),
'packets',
metadata,
),
sample.Sample(
'Total sender tx pps',
int(valid_total_sender_tx_pkts) // _DPDK_PKTGEN_DURATION.value,
'packets/s',
metadata,
),
sample.Sample(
'Total sender rx packets',
int(valid_total_sender_rx_pkts),
'packets',
metadata,
),
sample.Sample(
'Total sender rx pps',
int(valid_total_sender_rx_pkts) // _DPDK_PKTGEN_DURATION.value,
'packets/s',
metadata,
),
sample.Sample(
'Total receiver rx packets',
int(valid_total_receiver_rx_pkts),
'packets',
metadata,
),
sample.Sample(
'Total receiver rx pps',
int(valid_total_receiver_rx_pkts) // _DPDK_PKTGEN_DURATION.value,
'packets/s',
metadata,
),
sample.Sample(
'packet loss rate',
valid_packet_loss_rate,
'rate (1=100%)',
metadata,
),
])
return samples