<?xml version="1.0" encoding="us-ascii"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc version 1.6.37 (Ruby 3.1.2) -->


<!DOCTYPE rfc  [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">

<!ENTITY RFC1242 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.1242.xml">
<!ENTITY RFC2285 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2285.xml">
<!ENTITY RFC2544 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2544.xml">
<!ENTITY RFC9004 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9004.xml">
]>


<rfc ipr="trust200902" docName="draft-ietf-bmwg-mlrsearch-04" category="info" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="MLRsearch">Multiple Loss Ratio Search</title>

    <author initials="M." surname="Konstantynowicz" fullname="Maciek Konstantynowicz">
      <organization>Cisco Systems</organization>
      <address>
        <email>mkonstan@cisco.com</email>
      </address>
    </author>
    <author initials="V." surname="Polak" fullname="Vratko Polak">
      <organization>Cisco Systems</organization>
      <address>
        <email>vrpolak@cisco.com</email>
      </address>
    </author>

    <date year="2023" month="July" day="10"/>

    <area>ops</area>
    <workgroup>Benchmarking Working Group</workgroup>
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 50?>

<t>This document proposes improvements to <xref target="RFC2544"></xref> throughput search by
defining a new methodology called Multiple Loss Ratio search
(MLRsearch). The main objectives for MLRsearch are to minimize the
total test duration, search for multiple loss ratios and improve
results repeatibility and comparability.</t>

<t>The main motivation behind MLRsearch is the new set of challenges and
requirements posed by testing Network Function Virtualization
(NFV) systems and other software based network data planes.</t>

<t>MLRsearch offers several ways to address these challenges, giving user
configuration options to select their preferred way.</t>



    </abstract>



  </front>

  <middle>


<?line 65?>


<section anchor="purpose-and-scope"><name>Purpose and Scope</name>

<t>The purpose of this document is to describe Multiple Loss Ratio search
(MLRsearch), a throughput search methodology optimized for software
DUTs.</t>

<t>Applying vanilla <xref target="RFC2544"></xref> throughput bisection to software DUTs
results in a number of problems:</t>

<t><list style="symbols">
  <t>Binary search takes too long as most of trials are done far from the
eventually found throughput.</t>
  <t>The required final trial duration (and pauses between trials) also
prolong the overall search duration.</t>
  <t>Software DUTs show noisy trial results (noisy neighbor problem),
leading to big spread of possible discovered throughput values.</t>
  <t>Throughput requires loss of exactly zero packets, but the industry
frequently allows for small but non-zero losses.</t>
  <t>The definition of throughput is not clear when trial results are
inconsistent.</t>
</list></t>

<t>MLRsearch aims to address these problems by applying the following set
of enhancements:</t>

<t><list style="symbols">
  <t>Allow searching for multiple search goals, with differing goal loss ratios.
  <list style="symbols">
      <t>Each trial result can affect any search goal in principle
(trial reuse).</t>
    </list></t>
  <t>Multiple preceding targets for each search goal, earlier ones need
to spend less time on trials.
  <list style="symbols">
      <t>Earlier targets also aim at lesser precision.</t>
      <t>Use Forwarding Rate (FR) at maximum offered load
<xref target="RFC2285"></xref> (section 3.6.2) to initialize the initial targets.</t>
    </list></t>
  <t>Take care when dealing with inconsistent trial results.
  <list style="symbols">
      <t>Loss ratios goals are handled in an order that minimizes the chance
of interference from later trials to earlier goals.</t>
    </list></t>
  <t>Apply several load selection heuristics to save even more time
by trying hard to avoid unnecessarily narrow bounds.</t>
</list></t>

<t>MLRsearch configuration options are flexible enough to
support both conservative settings (unconditionally compliant with <xref target="RFC2544"></xref>,
but longer search duration and worse repeatability) and aggressive
settings (shorter search duration and better repeatability but not
compliant with <xref target="RFC2544"></xref>).</t>

<t>No part of <xref target="RFC2544"></xref> is intended to be obsoleted by this document.</t>

</section>
<section anchor="terminology"><name>Terminology</name>

<t>When a subsection is defining a term, the first paragraph
acts as a definition. Other paragraphs are treated as a description,
they provide additional details without being needed to define the term.</t>

<t>Definitions should form a directed acyclic graph of dependencies.
If a section contains subsections, the section definition
may depend on the subsection definitions.
Otherwise, any definition may depend on preceding definitions.
In other words, if the section definition were to come after subsections,
there would be no forward dependencies for people reading just definitions
from start to finish.</t>

<t>Descriptions provide motivations and explanations,
they frequently reference terms defined only later.
Motivations in section descriptions are the reason
why section text comes before subsection text.</t>

<section anchor="general-notions"><name>General notions</name>

<t>General notions are the terms defined in this section.</t>

<t>It is useful to define the following notions
before delving into MLRsearch architecture,
as the notions appear in multiple places
with no place being special enough to host definition.</t>

<section anchor="general-and-specific-quantities"><name>General and specific quantities</name>

<t>General quantity is a quantity that may appear multiple times
in MLRsearch specification, perhaps each time in a different role.
The quantity when appearing in a single role is called
a specific quantity.</t>

<t>It is useful to define the general quantity,
so definitions of specific quantities may refer to it.
We say a specific quantity is based on a general quantity,
if the specific quantity definition refers to and
relies on the general quantity definition.</t>

<t>It is natural to name specific quantities by adding an adjective
(or a noun) to the name of the general quantity.
But existing RFCs typically explicitly define a term acting
in a specific role, so the RFC name directly refers to a specific
quantity, while the corresponding general quantity
is defined only implicitly.
Therefore this documents defines general quantities explicitly,
even if the same term already appears in an RFC.</t>

<t>In practice, it is required to know which unit of measurement
is used to accompany a numeric value of each quantity.
The choice of a particular unit of measurement is not important
for MLRsearch specification though, so specific units
mentioned in this document are just examples or recommendations,
not requirements.</t>

<t>When reporting, it is REQUIRED to state the units used.</t>

</section>
<section anchor="composite"><name>Composite</name>

<t>A composite is a set of named attributes.
Each attribute is either a specific quantity or a composite.</t>

<t>MLRsearch specification frequently groups multiple specific quantities
into a composite. Description of such a composite brings an insight
to motivations why this or other terms are defined as they are.
Such insight will be harder to communicate
with the specific quantities alone.</t>

<t>Also, it simplifies naming of specific quantities, as they usually can
share a noun or adjective referring to their common composite.
Most of relations between composites and their specific quantities
can be described using plain English.</t>

<t>Perhaps the only exception involves referring to specific quantities
as attributes. For example if there is a composite called &#39;target&#39;,
and one of its specific quantities is &#39;target width&#39; defined using
a general quantity &#39;width&#39;, we can say &#39;width is one of target attributes&#39;.</t>

</section>
<section anchor="sut"><name>SUT</name>

<t>As defined in RFC 2285:
The collective set of network devices to which stimulus is offered
as a single entity and response measured.</t>

<t>While RFC 2544 mostly refers to DUT as a single
(network interconnecting) device, section 19 makes it clear
multiple DUTs can be treated as a single system,
so most of RFC 2544 also applies to testing SUT.</t>

<t>MLRsearch specification only refers to SUT (not DUT),
even if it consists of just a single device.</t>

</section>
<section anchor="trial"><name>Trial</name>

<t>A trial is the part of test described in RFC 2544 section 23.</t>

<t>When traffic has been sent and SUT response has been observed,
we say the trial has been performed, or the trial has been measured.
Before that happens, multiple possibilities for upcoming trial
may be under consideration.</t>

</section>
<section anchor="load"><name>Load</name>

<t>Intended, constant load for a trial, usually in frames per second.</t>

<t>Load is the general quantity implied by Constant Load of RFC 1242,
Data Rate of RFC 2544 and Intended Load of RFC 2285.
All three specify this value applies to one (input or output) interface,
so we can talk about unidirectional load also
when bidirectional or multi-port traffic is applied.</t>

<t>MLRsearch does not rely on this distinction, it works also if
the load values correspond to an aggregate rate
(sum over all SUT tested input or output interface unidirectional loads),
as long as all loads share the same semantics.</t>

<t>Several RFCs define useful quantities based on Offered Load
(instead of Intended Load), but MLRsearch specification
works only with (intended) load. Those useful quantities
still serve as motivations for few specific quantities used in MLRsearch
specification.</t>

<t>MLRsearch assumes most load values are positive.
For some (but not all) specific quantities based on load,
zero may also be a valid value.</t>

</section>
<section anchor="duration"><name>Duration</name>

<t>Intended duration of the traffic for a trial, usually in seconds.</t>

<t>This general quantity does not include any preparation nor waiting
described in section 23 of RFC 2544.
Section 24 of RFC 2544 places additional restrictions on duration,
but those restriction apply only to some of the specific quantities based
on duration.</t>

<t>Duration is always positive in MLRsearch.</t>

</section>
<section anchor="duration-sum"><name>Duration sum</name>

<t>For a specific set of trials, this is the sum of their durations.</t>

<t>Some of specific quantities based on duration sum are derived quantities,
without a specific set of trials to sum their durations.</t>

<t>Duration sum is never negative in MLRsearch.</t>

</section>
<section anchor="width"><name>Width</name>

<t>General quantity defined for an ordered pair (lower and higher)
of load values, which describes a distance between the two values.</t>

<t>The motivation for the name comes from binary search.
The binary search tries to approximate an unknown value
by repeatedly bisecting an interval of possible values,
until the interval becomes narrow enough.
Width of the interval is a specific quantity
and the termination condition compares that
to another specific quantity acting as the threshold.
The threshold value does not have a specific interval associated,
but corresponds to a &#39;size&#39; of the compared interval.
As size is a word already used in definition of frame size,
a more natural word describing interval is width.</t>

<t>The MLRsearch specification does use (analogues of) upper bound
and lower bound, but does not actually need to talk about intervals.
Still, the intervals are implicitly there, so width is the natural name.</t>

<t>Actually, there are two popular options for defining width.
Absolute width is based on load, the value is the higher load
minus the lower load.
Relative width is dimensionless, the value is the absolute width
divided by the higher load. As intended loads for trials are positive,
relative width is between 0.0 (including) and 1.0 (excluding).</t>

<t>Relative width as a threshold value may be useful for users
who do not presume what is the typical performance of SUT,
but absolute width may be a more familiar concept.</t>

<t>MLRsearch specification does not prescribe which width has to be used,
but widths MUST be either all absolute or all relative,
and it MUST be clear from report which option was used
(it is implied from the unit of measurement of any width value).</t>

</section>
<section anchor="loss-ratio"><name>Loss ratio</name>

<t>The loss ratio is a general quantity, dimensionless floating point value
assumed to be between 0.0 and 1.0, both including.
It is computed as the number of frames forwarded by SUT, divided by
the number of frames that should have been forwarded during the trial.</t>

<t>If the number of frames that should have been forwarded is zero,
the loss ratio is considered to be zero
(but it is better to use high enough loads to prevent this).</t>

<t>Loss ratio is basically the same quantity as Frame Loss Rate of RFC 1242,
just not expressed in percents.</t>

<t>RFC1242 Frame Loss Rate:
Percentage of frames that should have been forwarded
by a network device under steady state (constant)
load that were not forwarded due to lack of
resources.</t>

<t>(RFC2544 restricts Frame Loss Rate to a type of benchmark,
for loads 100% of &#39;maximum rate&#39;, 90% and so on.)</t>

</section>
<section anchor="exceed-ratio"><name>Exceed ratio</name>

<t>This general quantity is a dimensionless floating point value,
defined using two duration sum quantities.
One duration sum is referred to as the good duration sum,
the other is referred to as the bad duration sum.
The exceed ratio value is computed as the bad duration sum value
divided by the sum of the two sums. If both sums are zero,
the exceed ratio is undefined.</t>

<t>As there are no negative duration sums in MLRsearch,
exceed ratio values are between 0.0 and 1.0 (both including).</t>

</section>
</section>
<section anchor="architecture"><name>Architecture</name>

<t>MLRsearch architecture consists of three main components:
the manager, the controller and the measurer.</t>

<t>The search algorithm is implemented in the controller,
and it is the main focus of this document.</t>

<t>Most implementation details of the manager and the measurer are
out of scope of this document, except when describing
how do those components interface with the controller.</t>

<section anchor="manager"><name>Manager</name>

<t>The manager is the component that initializes SUT, traffic generator
(called tester in RFC 2544), the measurer and the controller
with intended configurations. It then handles the execution
to the controller and receives its result.</t>

<t>Managers can range from simple CLI utilities to complex
Continuous Integration systems. From the controller point of view
it is important that no additional configuration (nor warmup)
is needed for SUT and the measurer to perform trials.</t>

<t>The interface between the manager and the controller
is defined in the controller section.</t>

<t>One execution of the controller is called a search.
Some benchmarks may execute multiple searches on the same SUT
(for example when confirming the performance is stable over time),
but in this document only one invocation is concerned
(others may be understood as the part of SUT preparation).</t>

<t>Creation of reports of appropriate format can also be understood
as the responsibility of the manager. This document places requirements
on which information has to be reported.</t>

</section>
<section anchor="measurer"><name>Measurer</name>

<t>The measurer is the component which performs one trial
as described in RFC 2544 section 23, when requested by the controller.</t>

<t>From the controller point of view, it is a function that accepts
trial input and returns trial output.</t>

<t>This is the only way the controller can interact with SUT.
In practice, the measurer has to do subtle decisions
when converting the observed SUT behavior into a single
trial loss ratio value. For example how to deal with
out of order frames or duplicate frames.</t>

<t>On software implementation level, the measurer is a callable,
injected by the manager into the controller instance.</t>

<t>The act of performing one trial (act of turning trial input
to trial output) is called a measurement, or trial measurement.
This way we can talk about trials that were measured already
and trials that are merely planned (not measured yet).</t>

<section anchor="trial-input"><name>Trial input</name>

<t>The load and duration to use in an upcoming trial.</t>

<t>This is a composite.</t>

<t>Other quantities needed by the measurer are assumed to be constant
and set up by the manager before search starts (see traffic profile),
so they do not count as trial input attributes.</t>

<section anchor="trial-load"><name>Trial load</name>

<t>Trial load is the intended load for the trial.</t>

<t>This is a specific quantity based on load,
directly corresponding to RFC 2285 intended load.</t>

</section>
<section anchor="trial-duration"><name>Trial duration</name>

<t>Trial duration is the intended duration for the trial.</t>

<t>This is a specific quantity based on duration, so it specifies
only the traffic part of the trial, not the waiting parts.</t>

</section>
</section>
<section anchor="traffic-profile"><name>Traffic profile</name>

<t>Any other configuration values needed by the measurer to perform a trial.</t>

<t>The measurer needs both trial input and traffic profile to perform the trial.
As trial input contains the only values that vary during one the search,
traffic profile remains constant during the search.</t>

<t>Traffic profile when understood as a composite is REQUIRED by RFC 2544
to contain some specific quantities (for example frame size).
Several more specific quantities may be RECOMMENDED.</t>

<t>Depending on SUT configuration (e.g. when testing specific protocols),
additional values need to be included in the traffic profile
and in the test report. (See other IETF documents.)</t>

</section>
<section anchor="trial-ouput"><name>Trial ouput</name>

<t>A composite consisting of trial loss ratio
and trial forwarding rate.</t>

<t>Those are the only two specific quantities (among other quantities
possibly measured in the trial, for example offered load)
that are important for MLRsearch.</t>

<section anchor="trial-loss-ratio"><name>Trial loss ratio</name>

<t>Trial loss ratio is a specific quantity based on loss ratio.
The value is related to a particular measured trial,
as measured by the measurer.</t>

</section>
<section anchor="trial-forwarding-rate"><name>Trial forwarding rate</name>

<t>Trial forwarding rate is a derived quantity.
It is computed as one minus trial loss ratio,
that multiplied by trial load.</t>

<t>Despite the name, the general quantity this specific quantity
corresponds to is load (not rate).
The name is inspired by RFC 2285, which defines Forwarding Rate
specific to one output interface.</t>

<t>As the definition of loss ratio is not neccessarily per-interface
(one of details left for the measurer), using the definition above
(instead of RFC 2285) makes sure trial forwarding rate
is always between zero and the trial load (both including).</t>

</section>
</section>
<section anchor="trial-result"><name>Trial result</name>

<t>Trial result is a composite consisting of trial input attributes
and trial output attributes.</t>

<t>Those are all specific quantites related to a measured trial MLRsearch needs.</t>

<t>While distinction between trial input and output is important
when defining the interface between the controller and the measurer,
it is easier to talk about trial result
when describing how measured trials influence the controller behavior.</t>

</section>
</section>
<section anchor="controller"><name>Controller</name>

<t>The component of MLRsearch architecture that calls the measurer
and returns conditional throughputs to the manager.</t>

<t>This component implements the search algorithm,
the main content of this document.</t>

<t>Contrary to Throughput as defined in RFC 1242,
the definition of conditional throughput is quite sensitive
to the controller input (as provided by the manager),
and its full definition needs several terms
which would otherwise be hidden as internals of the controller
implementation.</t>

<t>The ability of conditional throughput to be less sensitive
to performance variance, and the ability of the controller
to find conditional throughputs for multiple search goals
within one search (and in short overall search time)
are strong enough motivations for the need of increased complexity.</t>

</section>
<section anchor="controller-input"><name>Controller input</name>

<t>A composite of max load, min load, and a set of search goals.</t>

<t>The search goals (as elements of the set of search goals)
are usually not named and unordered.</t>

<t>It is fine if all search goals of the set have the same value
of a particular attribute. In that case, the common value
may be treated as a global attribute (similarly to max and min load).</t>

<t>The set of search goals MUST NOT be empty.
Two search goals within the set MUST differ in at least one attribute.
The manager MAY avoid both issues by presenting empty report
or de-duplicating the search goals, but it is RECOMMENDED
for the manager to raise an error to its caller,
as the two conditions suggest the test is improperly configured.</t>

<section anchor="max-load"><name>Max load</name>

<t>Max load is a specific quantity based on load.
No trial load is ever higher than this value.</t>

<t>RFC 2544 section 20 defines maximum frame rate
based on theoretical maximum rate for the frame size on the media.
RFC 2285 section 3.5.3 specifies Maximum offered load (MOL)
which may be lower than maximum frame rate.
There may be other limitations preventing high loads,
for examples resources available to traffic generator.</t>

<t>The manager is expected to provide a value that is not greater
than any known limitation. Alternatively, the measurer
is expected to work at max load, possibly reporting as lost
any frames that were not able to leave Traffic Generator.</t>

<t>From the controller point of view, this is merely a global upper limit
for any trial load candidates.</t>

</section>
<section anchor="min-load"><name>Min load</name>

<t>Min load is a specific quantity based on load.
No trial load is ever lower than this value.</t>

<t>The motivation of this quantity is to prevent trials
with too few frames sent to SUT.</t>

<t>Also, practically if a SUT is able to reach only very small
forwarding rates (min load indirectly serves as a threshold for how small),
it may be considered faulty (or perhaps the test is misconfigured).</t>

</section>
<section anchor="search-goal"><name>Search goal</name>

<t>A composite of 7 attributes (see subsections).</t>

<t>If not otherwise specified, &#39;goal&#39; always refers to a search goal
in this document.</t>

<t>The controller input may contain multiple search goals.
The name Multiple Loss Ratio search was created back when
goal loss ratio was the only attribute allowed to vary between goals.</t>

<t>Each goal will get its conditional throughput discovered
and reported at the end of the search.</t>

<t>The definitions of the 7 attributes are not very informative by themselves.
Their motivation (and naming) becomes more clear
from the impact they have on conditional throughput.</t>

<section anchor="goal-loss-ratio"><name>Goal loss ratio</name>

<t>A specific quantity based on loss ratio.
A threshold value for trial loss ratios.
MUST be lower than one.</t>

<t>Trial loss ratio values will be compared to this value,
a trial will be considered bad if its loss ratio is higher than this.</t>

<t>For example, RFC 2544 throughput has goal loss ratio of zero,
a trial is bad once a sigle frame is lost.</t>

<t>Loss ratio of one would classify each trial as good (regardless of loss),
which is not useful.</t>

</section>
<section anchor="goal-initial-trial-duration"><name>Goal initial trial duration</name>

<t>A specific quantity based on duration.
A threshold value for trial durations.
MUST be positive.</t>

<t>MLRsearch is allowed to use trials as short as this when focusing
on this goal.
The conditional throughput may be influenced by shorter trials,
(measured when focusing on other search goals).</t>


</section>
<section anchor="goal-final-trial-duration"><name>Goal final trial duration</name>

<t>A specific quantity based on duration.
A threshold value for trial durations.
MUST be no smaller than goal initial trial duration.</t>

<t>MLRsearch is allowed to use trials as long as this when focusing
on this goal. If more data is needed, repeated trials
at the same load and duration are requested by the controller.</t>

</section>
<section anchor="goal-min-duration-sum"><name>Goal min duration sum</name>

<t>A specific quantity based on duration sum.
A threshold value for a particular duration sum.</t>

<t>MLRsearch requires at least this amount of (effective) trials
for a particular load to become part of MLRsearch outputs.</t>

<t>It is possible (though maybe not prectical) for goal min duration sum
to be smaller than goal final trial duration.</t>

<t>In practice, the sum of durations actually spent on trial measurement
can be smaller (when trial results are quite one-sided) or even larger
(in presence of shorter-than-final trial duration results at the same load).</t>

<t>If the sum of all (good and bad) long trials is at least this,
and there are no short trials, then the load is guaranteed
to be classified as either an upper or a lower bound.</t>

<t>In some cases, the classification is known sooner,
when the &#39;missing&#39; trials cannot change the outcome.</t>

<t>When short trials are present, the logic is more complicated.</t>

</section>
<section anchor="goal-exceed-ratio"><name>Goal exceed ratio</name>

<t>A specific quantity based on exceed ratio.
A threshold value for particulat sets of trials.</t>

<t>An attribute used for classifying loads into upper and lower bounds.</t>

<t>If the duration sum of all (current duration) trials is at least
min duration sum, and more than this percentage of the duration sum
comes from bad trials, this load is an upper bound.</t>

<t>If there are shorter duration trials, the logic is more complicated.</t>

</section>
<section anchor="goal-width"><name>Goal width</name>

<t>A specific quantity based on width.
A threshold value for a particular width.
MUST be positive.</t>

<t>This defines the exit condition for this search goal.</t>

<t>Relevant bounds (of the final target) need to be this close
before conditional throughput can be reported.</t>

</section>
<section anchor="preceding-targets"><name>Preceding targets</name>

<t>A non-negative integer affecting the behavior of the controller.</t>

<t>How many additional non-final targets to add.
Each next preceding target has double width
and min duration sum geometrically closer to initial trial duration.</t>

<t>The usage of preceding targets is an important source
of MLRsearch time savings (compared to simpler search algorithms).</t>

<t>Having this value configurable lets the manager
tweak the overall search duration based on presumed knowledge
of SUT performance stability.</t>

</section>
</section>
</section>
<section anchor="controller-internals"><name>Controller internals</name>

<t>Terms not directly corresponding to the controller&#39;s input nor output,
but needed indirectly as dependencies of the conditional throughput
definition.</t>

<t>Following these definitions specifies virtually all of the controller
(MLRsearch algorithm) logic.</t>

<section anchor="pre-initial-trials"><name>Pre-initial trials</name>

<t>Up to three special trials executed at the start of the search.
The first trial load is max load,
subsequent trial load are computed from preceding trial
forwarding rate.</t>

<t>The main loop of the controller logic needs at least one trial result,
and time is saved if the trial results are close to future conditional
throughput values.</t>

<t>The exact way to compute load for second and third trial
(and whether even measure second or third trial)
are not specified here, as the implementation details
have negligible effect on the reported conditional throughput.</t>


</section>
<section anchor="search-target"><name>Search target</name>

<t>A composite of 5 specific quantites (see subsections).
Frequently called just target.</t>

<t>Similar to (but distinct from) the search goal.</t>

<t>Each search goal prescribes a final target,
probably with a chain of preceding targets.</t>

<t>More details in the Derived targets section.</t>

<section anchor="target-loss-ratio"><name>Target loss ratio</name>

<t>Same as loss ratio of the corresponding goal.</t>

</section>
<section anchor="target-exceed-ratio"><name>Target exceed ratio</name>

<t>Same as exceed ratio of the corresponding goal.</t>

</section>
<section anchor="target-width"><name>Target width</name>

<t>Similar to goal width attribute.
Doubled from goal width for each level of preceding target.</t>

</section>
<section anchor="target-min-duration-sum"><name>Target min duration sum</name>

<t>Similar to goal min duration sum attribute.
Geometrically interpolated between
initial target duration and goal min duration sum.</t>

</section>
<section anchor="target-trial-duration"><name>Target trial duration</name>

<t>When MLRsearch focuses on this target, it measures trials
with this duration.
The value is equal to the minimum of goal final trial duration
and target min duration sum.</t>

<t>Also, this value is used to classify trial results
as short (if trial duration is shorter than this) or long.</t>

</section>
</section>
<section anchor="derived-targets"><name>Derived targets</name>

<t>After receiving the set of search goals,
MLRsearch internally derives a set of search targets.</t>

<t>The derived targets can be seen as forming a chain,
from initial target to final target.
The chain is linked by a reference from a target to its preceding
(towarsds initial) target.</t>

<t>The reference may be implemented as 6th attribute od target.</t>

<section anchor="final-target"><name>Final target</name>

<t>The final target is the target where the most of attribute values
are directly copied from the coresponding search goal.
Final target width is the same as goal width,
final target trial duration is the same as goal final trial duration,
and final target min duration sum is the same
as the goal min duration sum.</t>

<t>The conditional throughput is found when focusing on the final target.
All non-final targets do not directly affect the conditional throughput,
they are there just as an optimization.</t>

</section>
<section anchor="preceding-target"><name>Preceding target</name>

<t>Each target may have a preceding target.
Goal attribute Preceding targets governs how many targets are created
in addition to the final target corresponding to the search goal.</t>

<t>Any preceding target has double width, meaning one balanced bisection
is needed to reduce preceding target width to the next target width.</t>

<t>Preceding target min duration sum is exponentially smaller,
aiming for prescribed initial target min duration sum.</t>

<t>Preceding target trial duration is either its min duration sum,
or the corresponding goal&#39;s final trial duration, whichever is smaller.</t>

<t>As the preceding min duration sum is shorter than the next duration sum,
MLRsearch is able to achieve the preceding target width
sooner (than with the next target min duration sum).</t>

<t>This way an approximation of the conditional throughput is found,
with the next target needing not as much time to improve the approximation
(compared to not starting with the approximation).</t>

</section>
<section anchor="initial-target"><name>Initial target</name>

<t>Initial target is a target without any other target preceding it.
Initial target min duration sum is equal to the corresponding goal&#39;s
initial trial duration.</t>

<t>As a consequence, initial target trial duration is equal to its min duration sum.</t>

</section>
</section>
<section anchor="trial-classification"><name>Trial classification</name>

<t>Any trial result can be classified according to any target along two axes.</t>

<t>The two classifications are independent.</t>

<t>This classification is important for defining the conditional throughput.</t>

<section anchor="short-trial"><name>Short trial</name>

<t>If the (measured) trial duration is shorter than
the target trial duration, the trial is called long.</t>

</section>
<section anchor="long-trial"><name>Long trial</name>

<t>If the (measured) trial duration is not shorter than
the target trial duration, the trial is called long.</t>

</section>
<section anchor="bad-trial"><name>Bad trial</name>

<t>If the (measured) trial loss ratio is larger than the target loss ratio,
the trial is called bad.</t>

<t>For example, if the target loss ratio is zero,
a trial is bad as soon as one frame was lost.</t>

</section>
<section anchor="good-trial"><name>Good trial</name>

<t>If the (measured) trial loss ratio is not larger than the target loss ratio,
the trial is called good.</t>

<t>For example, if the target loss ratio is zero,
a trial is good only when there were no frames lost.</t>

</section>
</section>
<section anchor="load-stat"><name>Load stat</name>

<t>A composite of 8 quantities (see subsections)
The quantites depend on a target and a load,
and are computed from all trials measured at that load so far.</t>

<t>The MLRsearch output is the conditional througput,
which is a specific quantity based on load.
As MLRsearch may measure multiple trials at the same load,
and those trials may not have the same duration,
we need a way to classify a set of trial results at the same load.</t>

<t>As the logic is not as straightforward as in other parts
of MLRsearch algorithm, it is best defined using the following
derived quantities.</t>

<t>Load stat is the composite for one load and one target.
Set of load stats for one load an all targets is commonly called load stats.</t>

<section anchor="long-good-duration-sum"><name>Long good duration sum</name>

<t>Sum of durations of all long good trials
(at this load, according to this target).</t>

</section>
<section anchor="long-bad-duration-sum"><name>Long bad duration sum</name>

<t>Sum of durations of all long bad trials
(at this load, according to this target).</t>

</section>
<section anchor="short-good-duration-sum"><name>Short good duration sum</name>

<t>Sum of durations of all short good trials
(at this load, according to this target).</t>

</section>
<section anchor="short-bad-duration-sum"><name>Short bad duration sum</name>

<t>Sum of durations of all short bad trials
(at this load, according to this target).</t>

</section>
<section anchor="effective-bad-duration-sum"><name>Effective bad duration sum</name>

<t>One divided by tagret exceed ratio, that plus one.
Short good duration sum divided by that.
Short bad duration sum minus that, or zero if that would be negative.
Long bad duration sum plus that is the effective bad duration sum.</t>

<t>Effective bad duration sum is the long bad duration sum
plus some fraction of short bad duration sum.
The fraction is between zero and one (both possibly including).</t>

<t>If there are no short good trials, effective bad duration sum
becomes the duration sum of all bad trials (long or short).</t>

<t>If an exceed ratio computed from short good duration sum
and short bad duration sum is equal or smaller than the target exceed ratio,
effective bad duration sum is equal to just long bad duration sum.</t>

<t>Basically, short good trials can only lessen the impact
of short bad trials, while short bad trials directly contribute
(unless lessened).</t>

<t>A typical example of why a goal needs higher final trial duration
than initial trial duration is when SUT is expected to have large buffers,
so a trial may be too short to see frame losses due to
a buffer becoming full. So a short good trial does not give strong information.
On the other hand, short bad trial is a strong hint SUT would lose many frames
at that load and long duration.
But if there is a mix of short bad and short good trials,
MLRsearch should not cherry-pick only the short bad ones.</t>

<t>The presented way of computing the effective bad duration sum
aims to be a fair treatment of short good trials.</t>

<t>If the target exceed ratio is zero, the given definition contains
positive infinty as an intermediate value, but still simplifies
to a finite result (long bad duration sum plus short bad duration sum).</t>

</section>
<section anchor="missing-duration-sum"><name>Missing duration sum</name>

<t>The target min duration sum minus effective bad duration sum
and minus long good duration sum, or zero if that would be negative.</t>

<t>MLRsearch may need up to this duration sum of additional long trials
before classifing the load.</t>

</section>
<section anchor="optimistic-exceed-ratio"><name>Optimistic exceed ratio</name>

<t>The specific quantity based on exceed ratio, where bad duration sum is
the effective bad duration sum, and good duration sum is
the long good duration sum plus the missing duration sum.</t>

<t>This is the value MLRsearch would compare to target exceed ratio
assuming all of the missing duration sum ends up consisting of long good trials.</t>

<t>If there was a bad long trial, optimistic exceed ratio
becomes larger than zero.
Additionally, if the target exceed ratio is zero, optimistic exceed ratio
becomes larger than zero even on one short bad trial.</t>

</section>
<section anchor="pessimistic-exceed-ratio"><name>Pessimistic exceed ratio</name>

<t>The specific quantity based on exceed ratio, where bad duration sum is
the effective bad duration sum plus the missing duration sum,
and good duration sum is the long good duration sum.</t>

<t>This is the value MLRsearch would compare to target exceed ratio
assuming all of the missing duration sum ends up consisting of bad good trials.</t>

<t>Note that if the missing duration sum is zero,
optimistic exceed ratio becomes equal to pessimistic exceed ratio.</t>

<t>This is the role target min duration sum has,
it guarantees the two load exceed ratios eventually become the same.
Otherwise, pessimistic exceed ratio
is always bigger than the optimistic exceed ratio.</t>

<t>Depending on trial results, the missing duration sum may not be large enough
to change optimistic (or pessimistic) exceed ratio
to move to the other side compared to target exceed ratio.
In that case, MLRsearch does not need to measure more trials
at this load when focusing on this target.</t>

</section>
</section>
<section anchor="target-bounds"><name>Target bounds</name>

<t>With respect to a target, some loads may be classified as upper or lower bound,
and some of the bounds are treated as relevant.</t>

<t>The subsequent parts of MLRsearch rely only on relevant bounds,
without the need to classify other loads.</t>

<section anchor="upper-bound"><name>Upper bound</name>

<t>A load is classified as an upper bound for a target,
if and only if both optimistic exceed ratio
and pessimstic load exceed ratio are larger than the target exceed ratio.</t>

<t>During the search, it is possible there is no upper bound,
for example because every measured load still has too high
missing duration sum.</t>

<t>If the target exceed ratio is zero, and the load has at least one bad trial
(short or long), the load becomes an upper bound.</t>

</section>
<section anchor="lower-bound"><name>Lower bound</name>

<t>A load is classified as a lower bound for a target,
if and only if both optimistic exceed ratio
and pessimstic load exceed ratio are no larger than the target exceed ratio.</t>

<t>During the search, it is possible there is no lower bound,
for example because every measured load still has too high
missing duration sum.</t>

<t>If the target exceed ratio is zero, all trials at the load of
a lower bound must be good trials (short or long).</t>

<t>Note that so far it is possible for a lower bound to be higher
than an upper bound.</t>

</section>
<section anchor="relevant-upper-bound"><name>Relevant upper bound</name>

<t>For a target, a load is the relevant upper bound,
if and only if it is an upper bound, and all other upper bounds
are larger (as loads).</t>

<t>In some cases, the max load when classified as a lower bound
is also effectively treated as the relevant upper bound.
(In that case both relevant bounds are equal.)</t>

<t>If that happens for a final target at the end of the search,
the controller output may contain max load as the relevant upper bound
(even if the goal exceed ratio was not exceeded),
signalling SUT performs well even at max load.</t>

<t>If the target exceed ratio is zero, the relevant upper bound
is the smallest load where a bad trial (short or long) has been measured.</t>

</section>
<section anchor="relevant-lower-bound"><name>Relevant lower bound</name>

<t>For a target, a load is the relevant lower bound if two conditions hold.
Both optimistic exceed ratio and pessimstic load exceed ratio
are no larger than the target exceed ratio,
and there is no smaller load classified as an upper bound.</t>

<t>This is a second place where MLRsearch is not symmetric
(the first place was effective bad duration sum).</t>

<t>While it is not likely for a MLRsearch to find a smaller upper bound
and a larger load satisfying first condition for the lower bound,
it still may happen and MLRsearch has to deal with it.
The second condition makes sure the relevant lower bound
is smaller than the relevant upper bound.</t>

<t>In some cases, the min load when classified as an upper bound
is also effectively treated as the relevant lower bound.
(In that case both relevant bounds are equal.)</t>

<t>If that happens for a final target at the end of the search,
the controller output may contain min load as the relevant lower bound
even if the exceed ratio was &#39;overstepped&#39;,
signalizing the SUT does not even reach the minimal required performance.</t>

<t>The manager has to make sure this is distingushed in report
from cases where min rate is a legitimate conditional throughput
(e.g. the exceed ratio was not overstepped at the min load).</t>

</section>
<section anchor="relevant-bounds"><name>Relevant bounds</name>

<t>The pair of the relevant lower bound and the relevant upper bound.</t>

<t>Useful for determining the width of the relevant bounds.
Any of the bounds may be the effective one (max load or min load).</t>

<t>A goal is achieved (at the end of the search) when the final target&#39;s
relevant bounds have width no larger than the goal width.</t>

</section>
</section>
<section anchor="candidate-selector"><name>Candidate selector</name>

<t>A stateful object (a finite state machine)
focusing on a single target, used to determine next trial input.</t>

<t>Initialized for a pair of targets:
the current target and its preceding target (if any).</t>

<t>Private state (not shared with other selectors) consists of mode and flags.
Public state (shared with all selectors) is the actual relevant bounds
for both targets (current and precedinig).</t>

<t>After accepting a trial result, each selector can nominate
one candidate (or no candidate) for the next trial measurement.</t>

<section anchor="current-target"><name>Current target</name>

<t>This is the target this selector tries to achieve.</t>

</section>
<section anchor="preceding-target-1"><name>Preceding target</name>

<t>The target (if any) preceding to the current target.</t>

<t>While this selector does not focus on the preceding target,
the relevant bounds for the preceding target are used as hints
when the current bound does not have enough of its relevant bounds.</t>

</section>
<section anchor="candidate"><name>Candidate</name>

<t>The trial input (if any) this selecor nominates.</t>

<t>The trial duration attribute is always the current target trial duration.
The trial load attribute depends on the selector state.</t>

<t>Candidates have defined ordering, to simplify finding the winner.
If load differs, the candidate with lower load is preferred.
If load is the same but duration differs, the candidate
with larger duration is preferred.</t>

</section>
<section anchor="selector-mode"><name>Selector mode</name>

<t>During its lifetime, selector proceeds through the following modes.
In order, but some modes may be skipped or revisited.</t>

<t>Each mode has its own strategy of determining the candidate load (if any).</t>

<section anchor="waiting"><name>Waiting</name>

<t>Not enough relevant bounds (even for the preceding target).
In this mode, the selector abstains from nominating a candidate.</t>

<t>This selector leaves this mode when preceding target&#39;s selector is done.</t>

</section>
<section anchor="halving"><name>Halving</name>

<t>Candidate is in the middle of the relevant bounds of the preceding target.</t>

<t>If the relevant bounds are narrow enough already, this mode is skipped.
As the preceding target had double width, just one halving load
needs to be measured.</t>

<t>Selector uses a flag to avoid re-entering this mode
once it finished measuring the halved load.</t>

</section>
<section anchor="upgrading"><name>Upgrading</name>

<t>This mode activates when one relevant bound for the current target is present
and there is a matching relevant bound of the preceding target
within the current target width.
Candidate is the load of the matching bound from the preceding target.</t>

<t>At most one bound load is measured, depending on halving outcome.
Private flags are used to avoid upgrading at later times
once selector finished measuring the upgraded load.</t>

</section>
<section anchor="extending"><name>Extending</name>

<t>Refined already but the other relevant bound for the current target
is still missing.
Nominate new candidate according to external search.
Initial target selectors skip all previous modes.</t>

<t>A private value is used to track the width to be used in next load extension
(increasing geometrically).
For initial target selectors, the starting width may be chosen
based on pre-initial trial results.</t>

<t>If both relevant bounds are present at the current load,
but the lower bound is far away (compared to tracked width),
the candidate from this mode is preferred (as long as the load
is larger than the candidate load of bisecting mode).</t>

</section>
<section anchor="bisecting"><name>Bisecting</name>

<t>Both relevant bounds for the current target are available, but they are too far
from each other. Candidate is in the middle.</t>

<t>Contrary to halving, the candidate load does not need to be at the exact middle.
For example if the width of the current relevant bounds
is three times as large as the target width,
it is advantageous to split the interval in 1:2 ratio
(choosing the lower candidate load), as it can save one bisect.</t>

</section>
<section anchor="done"><name>Done</name>

<t>Both relevant bounds for the current target are available,
the width is no larger than the target width.
No candidate.</t>

<t>If a selector reaches the done state,
it is still possible later trials invalidate its relevant lower bound
(by proving a lower load is in fact a new uper bound),
making the selector transition into extending or bisecting mode.</t>

</section>
</section>
<section anchor="active-selector"><name>Active selector</name>

<t>Derived from a common goal, the earliest selector which nominates a candidate
is considered to be the active selector for this goal.
Candidates from other selectors of the same goal are ignored.</t>

<t>It is quite possible selectors focusing on other goals
have already found a lower bound relevant to multiple targets in a chain.
In that case, we want the most-initial of the target selectors
(not already in done mode) to have the nomination.</t>

<t>Otherwise (when in extending mode and missun relevant upper bound)
the closer-to-final selectors would nominate candidates
at lower load but at too high duration sum,
preventing some of the time savings.</t>

</section>
<section anchor="winner"><name>Winner</name>

<t>If the candidate previously nominated by a selector was the one
that got measured, the candidate is called a winner.</t>

<t>A selector observing its previous candidate was a winer
can use simplified logic when determining the mode,
as it knows no other selectors may have changed the relevant loads unexpectedly.</t>

</section>
</section>
</section>
<section anchor="controller-output"><name>Controller output</name>

<t>The output object the controller returns to the manager
is a mapping assigning each search goal its conditional output (if it exists).</t>

<t>The controller MAY include more information (if manager accepts it),
for example load stat at relevant bounds.</t>

<t>There MAY be several ways how to communicate the fact a conditional output
does not exist (e.g. min load is classified as an upper bound).
The manager MUST NOT present min load as a conditional output in that case.</t>

<t>If max load is a lower bound, it leads to a valid conditional output value.</t>

<section anchor="conditional-throughput"><name>Conditional throughput</name>

<t>The conditional throughput is the average of trial forwarding rates
across long good trials measured at the (offered load classified as)
relevant lower bound (for the goal, at the end of the search).
The average is the weighted arithmetic mean, weighted by trial duration.</t>

<t>If the goal exceed ratio is zero, the definition of the relevant bounds
simplifies significantly.
If additionally the goal loss ratio is zero,
and the goal min duration sum is equal to goal final trial duration,
conditional throughput becomes conditionally compliant with RFC 2544 throughput.
If the goal final trial duration is at least 60 seconds,
the conditional througput becomes unconditionally compliant
with RFC 2544 throughput.</t>

</section>
</section>
</section>
</section>
<section anchor="problems"><name>Problems</name>

<section anchor="long-test-duration"><name>Long Test Duration</name>

<t>Emergence of software DUTs, with frequent software updates and a
number of different packet processing modes and configurations, drives
the requirement of continuous test execution and bringing down the test
execution time.</t>

<t>In the context of characterising particular DUT&#39;s network performance, this
calls for improving the time efficiency of throughput search.
A vanilla bisection (at 60sec trial duration for unconditional <xref target="RFC2544"></xref>
compliance) is slow, because most trials spend time quite far from the
eventual throughput.</t>

<t><xref target="RFC2544"></xref> does not specify any stopping condition for throughput search,
so users can trade-off between search duration and achieved precision.
But, due to exponential behavior of bisection, small improvement
in search duration needs relatively big sacrifice in the throughput precision.</t>

</section>
<section anchor="dut-within-sut"><name>DUT within SUT</name>

<t><xref target="RFC2285"></xref> defines:
- <em>DUT</em> as
  - The network forwarding device to which stimulus is offered and
    response measured <xref target="RFC2285"></xref> (section 3.1.1).
- <em>SUT</em> as
  - The collective set of network devices to which stimulus is offered
    as a single entity and response measured <xref target="RFC2285"></xref> (section 3.1.2).</t>

<t><xref target="RFC2544"></xref> specifies a test setup with an external tester stimulating the
networking system, treating it either as a single DUT, or as a system
of devices, an SUT.</t>

<t>In case of software networking, the SUT consists of a software program
processing packets (device of interest, the DUT),
running on a server hardware and using operating system functions as appropriate,
with server hardware resources shared across all programs
and the operating system.</t>

<t>DUT is effectively &quot;nested&quot; within SUT.</t>

<t>Due to a shared multi-tenant nature of SUT, DUT is subject to
interference (noise) coming from the operating system and any other
software running on the same server. Some sources of noise can be
eliminated (e.g. by pinning DUT program threads to specific CPU cores
and isolating those cores to avoid context switching). But some
noise remains after all such reasonable precautions are applied. This
noise does negatively affect DUT&#39;s network performance. We refer to it
as an <em>SUT noise</em>.</t>

<t>DUT can also exhibit fluctuating performance itself, e.g. while performing
some &quot;stop the world&quot; internal stateful processing. In many cases this
may be an expected per-design behavior, as it would be observable even
in a hypothetical scenario where all sources of SUT noise are
eliminated. Such behavior affects trial results in a way similar to SUT
noise. We use <em>noise</em> as a shorthand covering both <em>DUT fluctuations</em> and
genuine SUT noise.</t>

<t>A simple model of SUT performance consists of a baseline <em>noiseless performance</em>,
and an additional noise. The baseline is assumed to be constant (enough).
The noise varies in time, sometimes wildly. The noise can sometimes be negligible,
but frequently it lowers the observed SUT performance in a trial.</t>

<t>In this model, SUT does not have a single performance value, it has a spectrum.
One end of the spectrum is the noiseless baseline,
the other end is a <em>noiseful performance</em>. In practice, trial results
close to the noiseful end of the spectrum happen only rarely.
The worse performance, the more rarely it is seen in a trial.</t>

<t>Focusing on DUT, the benchmarking effort should aim
at eliminating only the SUT noise from SUT measurement.
But that is not really possible, as there are no realistic enough models
able to distinguish SUT noise from DUT fluctuations.</t>

<t>However, assuming that a well-constructed SUT has the DUT as its
performance bottleneck, the &quot;DUT noiseless performance&quot; can be defined
as the noiseless end of SUT performance spectrum. (At least for
throughput. For other quantities such as latency there will be an
additive difference.) By this definition, DUT noiseless performance
also minimizes the impact of DUT fluctuations.</t>

<t>In this document, we reduce the &quot;DUT within SUT&quot; problem to estimating
the noiseless end of SUT performance spectrum from a limited number of
trial results.</t>

<t>Any improvements to throughput search algorithm, aimed for better
dealing with software networking SUT and DUT setup, should employ
strategies recognizing the presence of SUT noise, and allow discovery of
(proxies for) DUT noiseless performance
at different levels of sensitivity to SUT noise.</t>

</section>
<section anchor="repeatability-and-comparability"><name>Repeatability and Comparability</name>

<t><xref target="RFC2544"></xref> does not suggest to repeat throughput search. And from just one
throughput value, it cannot be determined how repeatable that value is.
In practice, poor repeatability is also the main cause of poor
comparability, e.g. different benchmarking teams can test the same SUT
but get different throughput values.</t>

<t><xref target="RFC2544"></xref> throughput requirements (60s trial, no tolerance to single frame loss)
force the search to fluctuate close the noiseful end of SUT performance
spectrum. As that end is affected by rare trials of significantly low
performance, the resulting throughput repeatability is poor.</t>

<t>The repeatability problem is the problem of defining a search procedure
which reports more stable results
(even if they can no longer be called &quot;throughput&quot; in <xref target="RFC2544"></xref> sense).
According to baseline (noiseless) and noiseful model, better repeatability
will be at the noiseless end of the spectrum.
Therefore, solutions to the &quot;DUT within SUT&quot; problem
will help also with the repeatability problem.</t>

<t>Conversely, any alteration to <xref target="RFC2544"></xref> throughput search
that improves repeatability should be considered
as less dependent on the SUT noise.</t>

<t>An alternative option is to simply run a search multiple times, and report some
statistics (e.g. average and standard deviation). This can be used
for &quot;important&quot; tests, but it makes the search duration problem even
more pronounced.</t>

</section>
<section anchor="throughput-with-non-zero-loss"><name>Throughput with Non-Zero Loss</name>

<t><xref target="RFC1242"></xref> (section 3.17) defines throughput as:
    The maximum rate at which none of the offered frames
    are dropped by the device.</t>

<t>and then it says:
    Since even the loss of one frame in a
    data stream can cause significant delays while
    waiting for the higher level protocols to time out,
    it is useful to know the actual maximum data
    rate that the device can support.</t>

<t>Contrary to that, many benchmarking teams settle with non-zero
(small) loss ratio as the goal for a &quot;throughput rate&quot;.</t>

<t>Motivations are many: modern protocols tolerate frame loss better;
trials nowadays send way more frames within the same duration;
impact of rare noise bursts is smaller as the baseline performance
can compensate somewhat by keeping the loss ratio below the goal;
if SUT noise with &quot;ideal DUT&quot; is known, it can be set as the loss ratio goal.</t>

<t>Regardless of validity of any and all similar motivations,
support for non-zero loss goals makes any search algorithm more user-friendly.
<xref target="RFC2544"></xref> throughput is not friendly in this regard.</t>

<t>Searching for multiple goal loss ratios also helps to describe the SUT
performance better than a single goal result. Repeated wide gap between
zero and non-zero loss conditional throughputs indicates
the noise has a large impact on the overall SUT performance.</t>

<t>It is easy to modify the vanilla bisection to find a lower bound
for intended load that satisfies a non-zero-loss goal,
but it is not that obvious how to search for multiple goals at once,
hence the support for multiple loss goals remains a problem.</t>

</section>
<section anchor="inconsistent-trial-results"><name>Inconsistent Trial Results</name>

<t>While performing throughput search by executing a sequence of
measurement trials, there is a risk of encountering inconsistencies
between trial results.</t>

<t>The plain bisection never encounters inconsistent trials.
But <xref target="RFC2544"></xref> hints about possibility if inconsistent trial results in two places.
The first place is section 24 where full trial durations are required, presumably
because they can be inconsistent with results from shorter trial durations.
The second place is section 26.3 where two successive zero-loss trials
are recommended, presumably because after one zero-loss trial
there can be subsequent inconsistent non-zero-loss trial.</t>

<t>Examples include:</t>

<t><list style="symbols">
  <t>a trial at the same load (same or different trial duration) results
in a different packet loss ratio.</t>
  <t>a trial at higher load (same or different trial duration) results
in a smaller packet loss ratio.</t>
</list></t>

<t>Any robust throughput search algorithm needs to decide how to continue
the search in presence of such inconsistencies.
Definitions of throughput in <xref target="RFC1242"></xref> and <xref target="RFC2544"></xref> are not specific enough
to imply a unique way of handling such inconsistencies.</t>

<t>Ideally, there will be a definition of a quantity which both generalizes
throughput for non-zero-loss (and other possible repeatibility enhancements),
while being precise enough to force a specific way to resolve trial
inconsistencies.
But until such definition is agreed upon, the correct way to handle
inconsistent trial results remains an open problem.</t>

</section>
</section>
<section anchor="how-the-problems-are-addressed"><name>How the problems are addressed</name>

<t>Configurable loss ratio in MLRsearch search goals are there
in direct support for non-zero-loss conditional throughput.
In practice the conditional throughput results&#39; stability
increases with higher loss ratio goals.</t>

<t>Multiple trials with noise tolerance enhancement,
as implemented in MLRsearch using non-zero goal exceed ratio value,
also indirectly increases the result stability.
That allows MLRsearch to achieve all the benefits
of Binary Search with Loss Verification,
as recommended in <xref target="RFC9004"></xref> (section 6.2)
and specified in <xref target="TST009"></xref> (section 12.3.3).</t>

<t>The main factor improving the overall search time is the introduction
of preceding targets. Less impactful time savings
are achieved by pre-initial trials, halving mode
and smart splitting in bisecting mode.</t>

<t>In several places, MLRsearch is &quot;conservative&quot; when handling
(potentially) inconsistent results. This includes the requirement
for the relevant lower bound to be smaller than any upper bound,
the unequal handling of good and bad short trials,
and preference to lower load when choosing the winner among candidates.</t>

<t>While this does no guarantee good search stability
(goals focusing on higher loads may still invalidate existing bounds
simply by requiring larger min duration sums),
it lowers the change of SUT having an area of poorer performance
below the reported conditional througput loads.
In any case, the definition of conditional throughput
is precise enough to dictate &quot;conservative&quot; handling
of trial inconsistencies.</t>

</section>
<section anchor="iana-considerations"><name>IANA Considerations</name>

<t>No requests of IANA.</t>

</section>
<section anchor="security-considerations"><name>Security Considerations</name>

<t>Benchmarking activities as described in this memo are limited to
technology characterization of a DUT/SUT using controlled stimuli in a
laboratory environment, with dedicated address space and the constraints
specified in the sections above.</t>

<t>The benchmarking network topology will be an independent test setup and
MUST NOT be connected to devices that may forward the test traffic into
a production network or misroute traffic to the test management network.</t>

<t>Further, benchmarking is performed on a &quot;black-box&quot; basis, relying
solely on measurements observable external to the DUT/SUT.</t>

<t>Special capabilities SHOULD NOT exist in the DUT/SUT specifically for
benchmarking purposes. Any implications for network security arising
from the DUT/SUT SHOULD be identical in the lab and in production
networks.</t>

</section>
<section anchor="acknowledgements"><name>Acknowledgements</name>

<t>Many thanks to Alec Hothan of OPNFV NFVbench project for thorough
review and numerous useful comments and suggestions.</t>

</section>


  </middle>

  <back>


    <references title='Normative References'>

&RFC1242;
&RFC2285;
&RFC2544;
&RFC9004;


    </references>

    <references title='Informative References'>

<reference anchor="TST009" target="https://www.etsi.org/deliver/etsi_gs/NFV-TST/001_099/009/03.04.01_60/gs_NFV-TST009v030401p.pdf">
  <front>
    <title>TST 009</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="FDio-CSIT-MLRsearch" target="https://csit.fd.io/cdocs/methodology/measurements/data_plane_throughput/mlr_search/">
  <front>
    <title>FD.io CSIT Test Methodology - MLRsearch</title>
    <author >
      <organization></organization>
    </author>
    <date year="2022" month="November"/>
  </front>
</reference>
<reference anchor="PyPI-MLRsearch" target="https://pypi.org/project/MLRsearch/0.4.0/">
  <front>
    <title>MLRsearch 0.4.0, Python Package Index</title>
    <author >
      <organization></organization>
    </author>
    <date year="2021" month="April"/>
  </front>
</reference>


    </references>



  </back>

<!-- ##markdown-source:
H4sIAAAAAAAAA81965Pb1pXn9/tXoJTaEpliUy3Z8cTKh922JSWqtWyvJce7
m0qlQBIkMU0CHADsVntr//c953fOuS+ALSXZqZnUZNIigPs499zzflxdXbmh
Hg7Vy+Ld+TDUp0NVfNf2ffFTOdRt8b4qu/XelatVV93RK9/91Msvm3bdlEf6
atOV2+Gqrobt1ep4v7s6Hjp55er6S7cpB3rlxfWLL66u/+Xq+bVz9al7WQzd
uR9eXF9/ff3ClV1VvizaU+/udy+Lb6pmvT+W3W3d7IpfWvnfP3bt+eRu718W
b5uh6ppquHrFs7p1Obws6mbbOrduN/Tqy+LcX5X9uq7dqX5Z0H9+U6zLhn6t
irLryodiVm+L8nAoHqp+XrRdsS/7fbGvusoVxdCuX/ID+rNvu6Grtv1LDLGp
tiUBp6c37PnDUR7zP115HvZt99IV+M+V/m9BS6M33i2L/942/VA2w0PT3tfr
X/1zgeC7cl1Xtxdfajva1rd1v6bTeOiH6tj7R9WxrA8vi+OtfPrf1vzWct0e
p1fy52XxY3sob7P5/9yVw22bPfr0rHfdib+IJnVN2x0Jbe4qBsVPb759/uLL
F/rnixe//539+bsvv9Q/v76+pj8dH2H05Yf3Hwg3BJxD2e0qOuX9MJz6l8+e
3d/fL6uhr5e0wGeb6kCfdM/4h7/t+mffv/nzFX387Pr6+d+uv/6a/pf++8Xy
+ssl/fDV9bNd/zd9hZ7cXX9x/eX189PytNnKVHINntDjgp4/oR/fvKrbq2/f
v/1w5TF/elnrvh6W282ybp+t6Wr0z44VocSmPbS7B/q77M9ddayaoX9GV6L8
2+lQNtXfhj0h9m5/Og/P6Nb8TcZ/lqzlzSsasuAVFB+qfijehWGLq3Adn+Aj
f9teXD1/Tr/8+PDj208t/PRwElieuvZfq/XwzL//7HpJcEuX4x8WeLigKWg9
TfFjub4tdxXdz031MVvMcyYE7urqqihX/dCV68G5D/u6LwhOZ4ZJQVOf2r7q
i/pIf94JoPiu/UWx5a9FAFWhC1g9OLqWdcMEoiya6r6IQE6X/nCoNpMkTQnY
zO9lviw+7KuCsLop2hUDgZCqLwglA4CJelS8oiNNeKx/pb/3lRvaoTwUA5/L
5tzx4M3ClsdfH232A8+OF/qibDa2T9dVPchKV50qerqqD/XwgDfoOp3KrpRf
lgwwXeCxpdVhqmJV7Wt6NayRYErLAiz6aijabbHeMxyaXYV5ab5/O9eKiAWD
fENgxAYYit9Xwz1R3OLNuVljgj/X3XAuD/WvmM/N6O7MifKBGmCVLU3XEa3c
DvcMn1XJIzY6DCN6AUTvaQNhle12W3U9rZBuLoHvvnzAWZebDYEDOyBiHRa+
KHb1HS+PaHhHZL7Z1jsFNnEN/h983lcHOjj+uu4IoSqao6PF0OhLQb5jvdkc
Kuf+z8uXBFwGwf8Fnt70xX0FBnHblcdNe9/wcDQPLW8otl17LJgf8YMFPtC3
B0ZhGp7BbAxLB+6Lph14lFVV3NV9vSIUoKPrKrodvCiwzCUGs2tI5Ht9SyjR
bQ/tPRPTZ+WzL1988eKLL76+xotvtwptAkrdVHzWtIrNwq+UprMlvfzk0C+u
f//73339+2uCxjMPDfeb4sdzx2iBw32/bk+VYN5Jf6atDsnNrQH7TdWvu5o2
+3nXbUH3dXyf49vL58q3bINrZPjlXv38gVHp5nQ6PDC478qmPhzKaTKxqvtK
0Jixw1CUh/DXjs6EKMf5uCKw0tboTtJJHXtiSFfFN3VTdg+2uKG8rXirLV1l
pjc93cMeN2zo6vLQgzxsWjqXbdkJ0jCBIF55R2CiO3R4oK2cCaphhUuahYGr
l5L2SlMeZEBPT4oZH8WpPDN5XNHNqqpG55yTHNO3NAetG6viu9/iUh1s3TYM
z/U+hkHR79t7QtO6f9AZDSgz+bGp6t1+1XYGlTkj/6EqWcoCate7oqd7Vm4A
OjpvoPmGhYE7YHl0Fnfl4cxUgDfsf9R990IdaZDqI/EGAtSvVdfSlte3xNYX
xeqMW02HtSGhsXugZWz5U4IrvUt7be+FVvdH3ji/3rTNFQbhkW3eqhB2IYRj
Gy+vlgu7pu11xf3eIOxBUkI6rBu6an1N1K8ZEoJW1scJCmbYxBS2NIzljWxb
XjP/i4i04303+7JZC1UG7t3wC3qE/F7CS3TSXUunvyju64FOuWaSym/yrzG3
YSJzVbwuGYWjLUEmLukjophl8xCPyZfiRGOteTLQkZl9STg4Z1j6W07Hv64E
ISBVyDlUPFs04oJ+6Q413zFiBYRY1QayNqEPEUTCKQZZfSTcNcy2VctXNjZj
O8O6KAd8VIHOk/QJ/OYvfiawv2k7QnIsiuhPVcze/DTnL47lx/p4Pgr3Iew8
tOUG2/uLCqd/LWZGML5YfrV8MeclAl+YA1aKg/inLQmIRZSBwEnXCoizqeht
mhvnEmNMilKy3u8isQDnCTJCyLBh2YWpE2Fqt2EY7HkLKnsIl18DabAFwqGa
FSPeGf0m9OdAu++MPNFW7BAwEa8cZNSzYYaHMlEGwb46d7Twei3MtbyrQMqI
7LEcRKdFE7Po0AGt9wRx3IC7tt4U56YhvOj7sqtpAiKjHWHziqlfKghM83IG
wfZQfQQ5qRq+ozS068+nE+lkNM6AL+n476Aw8C1i8YUo15nhvcENB8VlIepQ
k0olx+HZxMIxlWCaydJLSinB+kh+6SuVylQGm+NBudvxFadpXZiWSGk3XBiJ
SDY/SoZSGkXq64X10S1z3zMJ7MBiAnurexw0iREbFS/aVd8eqkEFuZg3L5mf
f6g6whowVed+YQQti/68MkTn14MMTQs9LoRE1R1xNxZAd115IvV/zfeP/i+i
ocviB8gj/i05OtKaS16Ovs2CAQ524ejtB6aKd/WmYlqp50QvDaRP9oBBy4y7
4uUwmZBdYkq5f7xC2tcrvwjwsfMBcsKRJySGssb064f1oV4XWBkDcVMxtaHr
UTNDIGmKAKFQIKShFfBYHjK9wMHeCLt2R5L4ZCzQK34pwDO8R3MAPPckhSxA
YyPuk44RqGjy+dtGBT5Cxg2tp95eWBIJpKKbEDoRYLdAxWgnDHgmT4AToUzT
MrSYSCZAAe0+VS0T9k75/L+eWbUJq3KgLCRQirzJv/d7HIg/594fcdBURFmo
PrIyUIZFPcSMHBI7qBcfsuJlxQCih6BlS/cuGpGoYwBFNDtwEFJV2dNx3e8f
/HtD9XEAkFiS2jIhi46OH/KV+U3xx6oBRaQbij277Ac/RbrQupH7pwPSWG8H
ldK350OGyEEGsFl0RZvqAGWHrnmbaJ8kCQw08rmrFq5UPc/Wczqx4MLKoefM
h5IosANZofPGP/ViEdddMyfypLXYt8kpAwoBDHx0+GZL1+nfzkSt6K0qAov+
9sCbLcO/hGWVD7Y8vzbmHr2j1Ybt2fiqQp+qbl+eepEkIBpAUhcxh3kpCbzV
EpqJnw7cV6YS+PEFp78Ym9sD9CWxCbhytJ2Hxw9rl2104fo2vhVMXiYghM0D
rSFJEHb9QhjHABkvgOcW7Zn5xsSMdvtHH0Z0AHOJJApd/8CLUCKVj5iet2ye
7uaZ36EB2DA4uScWZjegDSxBbtRY4mZEO0iVIh4/F0W0kiHa7eTsS/cNEXri
8WJ4IP5Gy3441WuwbSYU9bpmqqCnILyJiDq/7uRsbXF8ugtS8DARjSQTCyMw
uiJA8d84D1dCm/ogp7xuO2LtJxYgWJDOVuzqjCTVR1skELGT65twYPuiz0dj
QIZNLhwkKzthXr3s9sBk2O5Pr/Ig7ZAPjNkGg2NNe69xel6NpK3eNiRx0dbo
+pzpkGGiCDZIp7YDAGUNS1PzIJowaRFr0dagkPH9C2f2AVJnS3PywxLySb0+
H+hyT8xiWhUBisQjGsOlBrXkzhfM+nd7nKM/WR60dzwWvRFRWG99YEIMFkWa
Ix0HYzuLWmLQ2Bin4UXEhq+lSkIkk9HC6LANgj+9/h8/v/3p9StIvAMrD3wg
WAXgpYTxWwJY2xM1du4GIib+IdRPzW6MgiSDDCR9k6zHAgdUMP8Dv1zV4O5T
xACXyY+cyMwp1CL+uWMfSR+piRMkG0wlHrmIGDeo2JlXGW1q1UHEJbwj+aje
7QfHNtCIDTN/xaHQmkVcEa4Ie4jeF2FXD/zb0r3nKXQwEvlYY6+gPwiZ5LMj
iNP+KuFeU1SP709J4juD5oa0Qhxgjxu55WcEfr7D02R54ddz7sUwQ8qw6/e8
YiFhgL+RNiEgnVo9xLzIi4Tc6E/onVqDiOgqYMxW418SIUgGmDocVslXlbel
kRrF7ItZN+H9a2JkImr9qLwRxp4G1HJdyQHWzV17YMt1suSpuVg4D8jJOrNd
ISVDneJzwAQ1qD8V1fcpCSGQXkEK+IJMnRENoe/TSW+G/VOPEtibGzO64qm8
uGArK0OE+aX8xqPpfDpm2MJTvZrvf/5AGJHIZMwRxPcE8kVyl56rXVWzVld3
RNjAKIRwEmuiy3TGLtRoALiZVFHJghkMwjdIY1TytwGJYcaC2Ul1g7kw4Uav
fv5QRMO5mS0EmjypJE0FbjfXlS28GPv8a5Is2BxZq8nK+UsPy54iUqKI6ZrF
dg/5xeyXfoViXjmdIDUwqqtXgGD6CAUCCoZd0ctsQBx4JfPA2HilYgmBsASa
7Rcl+9MT/MD2CiasYi5Rj4ZpwuJq8TfEjpeXb9B58YXR96Ert4yQ+5JvY8X6
AvMMtmzTKv2Z+cekSlfdXbVZuHuR0yDjYxn+HZJMWdNku3vbTb0QMOAbkwhI
DN4zD2elMgjoMJiyOcBUr/OJLhvuLEDAwuOKuQ8TRgCP/igj+fw7NmC5t2oO
gB8A7mOx5GzBQzDUwhO6mjlGyfrPCeYKtpbQaDySQXp0IUFVxbzwrc2ADxR3
2MW7cK/Y1wN7W4JSBGtbYPIRX8glke4DW2ErI/DKSUT8iDCRb/2sbthSy1zm
PNBfc7V4kV4DdFZyMZSH26JcsRmBuIgIgWJlAFRgMIemsEoemn31CiYmQ5y6
11VskguwaSuRbIjYP4h8zUIJZNm1KDCE73yX1WZZb1nblRWIJTwSNkVcF8PS
jgHYMeub9WyqvGP5gIDE+MqoD5RPwBCgMLXffg5d0VwWPBR+LoTbeXGzr458
2msWjd6rPRAyuYrfqhXFaoDpKj+oORXYSIdEi5RjTs59Lmb8C0TECaxASsDz
Z2bkmmO97J5l79NoGY5ADl8HXVvxyQTBhC/Alh2hE3wJwm+sgLpkPalxv6ej
qNTfEx8hQxC8kZjJ0r2Bn4pgOVPjHkN7Pq1CGex4tIWDowJ6MuPKioUQmqHW
efSyv1KbYrjwwcyoOpZh7aWbL9e9X6rzfawQGloTFh/ObKJr2FxXsX0P8zQ0
8H1ZQwVLaHAgvfHtJ1HPfv8yoQpim4gtgHQVaL1rVaab4Ex34vxpYYz174g7
RfAFvr2gaF6Et4uGZYOVAY/v+AEuaDvLBDEy8JOAfHQ460hsV0FCLO0LoQZK
TXGLtyr02fS4ZbrmR/FjE82qAnVHC9zEwqwzq+mlBQFC5+PEGuJNQVnjm0//
f1deAsMvLIdNGH5M3ALqqcuiYq8lzTg7tPdMxojS7Unmr7o5u7yii7RQectQ
CnbjmhkNTFbq8WQEv2+9I1HiIUIoxFa5MXR/MfHBVLmKvbiiwa5Sx26nTIZw
qms/1kcmwRww1rAO3ciEbvWgFvxqQzinnmWxgYAA3zEPibygujN3Jvgc1HOk
r60qWZ66RcQKt3QArWGxf1l0ylw/dKpIQNWqxaJaeM+Hho7AS1RCXysbjdMY
KZqlbkOwlXlxv28PGwGU/6dyZE8g9uwNitbll0u0sl3XDCW5uYHLqQHmaV//
Wj21bepCN36AJcvu/IpsnA3f3gpiNDt14kKcwSfE6cQ5ZVYsfK1IpRZVD1Qo
FIpFlyRbbJcDPWYl0ah2xzS/3c5JTmPhCe4sHITgN/4tXM7DiaAr1Jd9GRCp
g3RiqyFcfs9MbJEcvHCXYGISlQzWEa8LCbrLXhntWRfWCReqwoHJ0605tSdY
aczFxrfF+30UFjfsSGLThJ8g5VOYTxBBJ5frLI5UQsOz/CrgANt2P0EbvovG
3NRHkoNpEezAnRizTFbhNjV7EtS3lcy45Lgd7wsTqQZEIIRjGEFfuG60DqMr
18trljaY4UHX4gN9zr+RVq2/EVyzfUCjym+Hyesio0CgJ7mkJ2mzJYwAPpzY
+XtkR3E52IbV6mmKBYge4TVJfHKFUoDYLIrq2/JIGkQJ/YCNAI/oaR4peRES
rCNkV8Zl/UUciggqwtR40hfvfn7/gR+YvYoELr+oVv5t8BWjAAm/9o1EVIAS
i7VNJxVEJGlCZDESHAEQ0zUsfmbSrMimx+ZB1w3Yz71GZO50udkhDkLoyciq
nqJjsSU0Aj08tYRZSvpF/jN3a4w3iisLcUl7JFqqNZ2p23nw5q8ozkh1MHXC
CXrzgRcB3d3kF9Al1eEJIgyVM4xD3N2CTHAP2FC8nZ78U0PRBlgwXajmEgPS
lFEPFH7RQe6VY1SfNz1k8smX1pxNck/pAWHhHYIiSFiaQwWNZyDKo64Ar6IE
ltUXb0D0LcSsSjVR2BYY0auPjOrKNeh6rdX2q2HJ+Sgv2bLG73AY62fDiSWD
MrMhqc4OTehBDckz087nDqIPhoXflpcanyA8uSQh39IiOFCtPdOqeN0zjQLw
kvAYEOCxRFGwgZVF0i9geBfQP7++/i/88KmFw7C2+XRRfE0/w9HH2vZyLvfp
9cc1My5/o6a0hlrEtU9do4VLLH/gSol4G0TapfuBVM5NJpz6gE7eo5oq2naT
vCfIKrLO9CerMv1CBJ0q2mdgR/n9zb9V+pCxqCDxY4/0z37JsZugEfwvsKZw
tZK52S/TKKCWMGQGPt60QTSPl9EngvrCjTcjU05QLtJVE8oldLS4iXzNiSYc
/Z6Y88SGg+hk2IsbCWQbELLc0H3qFirvNUPHBtjOTOFG2DuVxWymw67tiN0c
jSmA8psHKB7Icxxlp1jEtl2f+1GsKjNH1uH9eMoYNfpED00XPFogYgBZcGOl
jQNjR+Mv1BJvcWAmeDoOtNy0qsYGAEWmG+/oCBtTlvZOlmPx37I23asfSqhJ
CFXrhZuYQUDu7NB2bqZGfNiSuth8Ol9ku9XthwU5jWhTiSuJ3WIUR5Bmo8Fr
ssDqY7U+w2qhLuEMATjuBZH2NULgOTCOD0l2KXbsrmx2Gs8G/05VfPvd24IG
VcOpeIzo94/uWxqcpNCWjp5tJDu7IhKuviRiqUJFtAqhUHSSd3V177wQIv5K
AWvTxpaKNGRtJiaR7ng+zV3dW8wSk1s22Y1wiBmfyHk+0BEHGzAh1ndzVIzO
os7CTpJNhQAUJqT+EILW5d/0MRHwXIqKDMuE5x0SxCBjVHkMaoguAItm58ts
G7mScBEAse5ockks53KwzFCyvgxLJwd6zEX0HHl6YethOzD7uNbedAO5t2tY
ggTZ74vYbN4PzCHK1IXABxNZtZjmfcueEoWQiKkgB7AInDrWZwtJT5KwWTXT
hSksHkddCpbGkVIUNmImOS9iBYsd02yjEvnY50NxJKYXzWVt3g/9TtFKiYMh
2Yg6yJAKePGhiYuh7D/pS1nIIcLN3A+BzSWE6pM3yxzsZbG11BLcrXLNBLN3
6uuBaVsIA/EYTuvA72LpNrtlHbk+78t8NTghXCdSvoWuwn+VxEskd1LBu2Fe
vRrgjpKQ4t4Z/nJ6heGvOYmAR6uKRMK67Qp1rKsrT5YdCc1iyU3crMwUEGXE
lgpapvEWCfdV4ZPV9DPbAICC+A23OqQzZMzsQFL1Idug+HHpmvNNW7i6+VeJ
kNST9EylGRPpuhEznJIpBilbuQST4GE3XCpm+pAPzjux5EhB/aOTnCd0J1Lt
xKeGN6Nfl3LufNZjJ4/ZOL04bf43sxuJrSx6q8RLcN1wOCKTUDgs/YcP1aAK
pXojdReqUrIXqYkkQdVyJDgn9eFFKJuGc0jgbGTyVcZhRxLJHEWqf5oagW2x
nfd8yg/SQhvVCsCxmhyjXAUPAZG1bX1gWitRUw9moFi3Z/aQ9kVyIaMoFkDF
wALDjwt/29VMrDLeMjuGyNgcmXlGfAxXGppFkDAfYjpXtr6N95mk/x6t0z/4
h9YaZf61iEORVysm5wdzIivgzY1tcywkUYz+qY4VvNIH9EsOjDSC5kH1m1QQ
UTn/AhpFYkcZ7S16gz/sRUfJaXGGNIkME0B1k+KMj6j2pFpXiCt4x/Z3tVW0
GmNp6ks+XcfJxk0fvNuRjcP7JjI4Cc9KRYA4lCUO9SJYGdtzkvbHCxef0pRz
JhFwgvV5vvSOU1jmLoWD0hX+6fW3P7x79/r7V69fIXKaI7AFEuApmYRZLXdL
TUnSeAw/NO12aNftAV7eIKJGuKBEQx16XlbMYCwqlD7iAAuRM5bF7H1l6vTb
1x/ehLhGNRDYRWvPoI9xMJyqhxqFlTPEQJTN9MEvsikCiIkERPVPyx26nwxj
IqZzZNd2m5FTp36Yh0DU/c5x6eIzjPOB5s6ziKAFJFGLIxIYWRxzrv9pImev
ihnCWx5gTlW7RRxk6Xcj22D5zf+U3flsnRmUbbHZz2rMSZ2MD1P2TL61avLP
dr0QEKqmoIEjg+cRkitwqjW2kv0Wi+m4E4mlH7m+MpdS3QuXAQvnPcwFlvAD
IluGJlP4GNMIDkcJzs0yxnwsgIWe5JEW3jKT+aLSo+cFNdU65EER1bzyY5C+
IqFsZn44VNvB8x87xfnCzGXpZCT7cMx1FG1he5traBh/Pn3DXPB4m7KJCATv
Uwz8fNI85HFKFHZDJc0rzIMGJ8hALlVExEAhnUgcgRwgrTVDiCq7LekViXx7
4HA+LC8K1kmTaiPGZ8ceWQScmnbUc+Y9diPV/RFL10LNDPTPWnhzLs4aZDM7
ElSGdH+M31siGsiaSac11cTHLHvbgcZBmnZI53LBxIeLzHJ6n2zAxRpalG9X
hITa3nIATPdVUSrM6vWWPuLkwe63cN6Yx3vSdebmPGyKZQmaLcorLkfxn+IZ
GN/Y6dXz6ZBSPvCyGnEhThiwBFFmpc93yjWqudkme9J6D4d4ahG3LPMSAdNO
vXFwNIChceYYYqPrzYZTW9Rg2JTBWBlbhBJF0BS2YIm4sFUREGC2TzYbm2lI
XKv5j4XH5TK1cETLkKSwzUW8uJjJDPMi199o/O8zlUuQXpkntsNYxLWDSMPp
WAhQD1MeAgYuw6IQcmTXnBVWbcxmKJk/6f0wbS+WZlDh4aP6wYnv6V9ICLVo
m3gzqTVbMnsZUyrDeYtWGn8qe7KwLTARySVoOK9WI2t8xg6i87SgUTJbNAG8
Vt5IJ06LPH3DU9xl8baxi99XZrZHtLt8qUJsEly8O7Qrjv7w2Q2zvj7WNK7E
ZzHoePkGuLkHz2j34jj+/gdxOB9PyDq5b9N3FFNsf/hEUsOghXNyeMmxzZw3
5PeVGNDf3fwvTVUWDkcqtqQ2sceQ47oZn3h2FYUd4iWuzBaT6h+WiR/8n5GE
7zxL16kJHl1Zo8JGUXVdq7lhahDpfG4fi7z+EjE/3+1YNPcyeq3FcuiiQkEW
pcFsg+w4+KgKuv31WUr3kvOOh0SlR1SYRl4QZqhl1oITxzbDay9YmY9R1CQI
H34y2gjpSQNiH2JfpL+0QbcyIzNdg7pcOq/7h2z93y2/CGo3b32U6V/M3v3w
3VyJrOKwRKpgS+OValKXvSsqxoHQeigtyxUebDDm2lzb4mr12UjefUvYRlIe
TN0whmWOmeXIv1N9PImVDr5yTZlWDWHQ8BEmDjvcw85hFxwWIVFrYaHL4uYA
rsGUXSODAivPZoITW2olKInzmpRPlioQUNyzBeohcZJ7b7Ztk64hUR7Tzf8Y
bfYzDMYWRammOk9kJPoK+3MSbhirF2we3NRcecrbUN4p1aGLoH/9UxchQprk
HuD8QjyiSSuxnzwOe4D0pglObYtAZYUlkhQkk8JnN6npWiJ5mXSzoYB3oZDu
kKgndpaKYxu5EorLBH9iQUcPgcbb1mDO7vOYJgYty5sYaQ6ZVW9CFP2BmngP
xQx54yEryejTkUvBGF3yysP7QDRHTPZfItFfTJZRHvtcolkYw4J8ZLeeUPUp
D/nUdJsk7TOaMvcsLU0ezgQ73q0ZgyYFlkjPvFz1CBFOa+WVKw7qYKHeZVVa
8JY3dgQ2ito2cjNhMjMNw2QM5BRiLOTRcUoUOMm0qBcq86gEL84kvu9w1jab
IDWYXS2RmL1UkRxTqbceiBfV8VNp+NhXnJIGaNVdfEUg3kmm3txHxcJ4JklN
PgiM+Fwplb0eRJiJo12TPXqrxx/bzDhz87mGmJsiD+zzUYVpXR0LcYsIgiQk
juxAapCzXEcf9WoFuzRARk2z0Xv+onHoSS1pdqmRIWfLSwlOVwa0CB69CA/Y
4ZUjIB2shKTYIhCExcBZI9K33nlrZy3kP43ZYsdVYyUm1oeSmMb2QdP3MR7m
bIkNc5JLt4HCoSYToi7q9BSWJhGU6VH6ujuZYf/RYw3h/o8dahQRb0casjpc
Ulsvuo8oAKehpr1qKLjE7KnaVxqDwtEflh/EIF8arZm6n0pfvUYPfdJKy2hy
gZt5A0AyC29XY7xjXWI5rnb35u3/fPf6ZfFeItrS4SF0h9z7ekf6RrX5r1mN
uHAqU/XK/r3OpGmFFxm27y6jxWcfm+VFferUOH4LhAkVDX2cx8LnBBg/V1IK
RWvsKWRK+bgjPYIts+pNknXyWXCVoLZp2CYaX/pBBDBflc0rUgBEeYRvkO7s
rELdMLofc9v3aHSJcWyVrHu/V1QDEsa13iuyPnNiJoUA+DasKgtYFuFnjl3s
JqEjdowxhkyhaF4+YQhhex7xQuw+FykbfGmypIyCJtrarLPpynFqSyL6eMX0
fIOqw0iMPXAac8d2XFU8JfZbL+UV7+JqsiagHz3Dt3kI+NUNsWFgBsqLYlQl
MurMPy2+zfiYF5ZaEoIOhbaF5Ca1cJpQvDuXHSEj13RTD7VQ/1qMAxY03qjg
DkSJMibkLOBtY4ODpgTYGCHQR9SaviUodguxjPKLT0nG5Pv61DZERwJH9h5x
Y5CpzgPjoCUFx9uRLAFR+Re6q53kfYocgvJcHHyxSS9nlQTGPnox41cvXUx/
cbgWplqHLDzspokEQuTA8BfGYpn0S2AvwjcExllSSh+QIglfNexYnzvU1LGH
8wnkcPmFE+PXUROclViekgDqfEIXp2WVmwilzIlT9wFRPHZsI3Q0dhWCLwJa
fu7ZSWLJ44dmKTGfJqP65oTkINFeagmBgP1RsuA1S0vsHOzjChxbUk2qO3Y7
ytmRciWQVDqAwgfz2LmLMdYkSFVWQuqCfKHUKg0iI6j8mBdxZOBwBc0oE3Co
EIgohF+tXz74aWQFpqH/xL4KVJUJjmkeM96G1czU4igNV+fKK0pCWt20Z2YN
cnJmSUxweVcRbnFQvNTzYGh0UfnGMQNgOezcK6aOy1gKJgYfsJhxXMLCUJeq
L++kBmAs1UukajfyakAg+xO+iCT/4PHnTR6qwSKZJfKXVL7yVijZdGnXgLaa
X7QBtTxUmx1WjIDHyJzfD6Gq9Mj0rQ4GAhCquDAtvRyFk576015V58Znp0sw
p0alRDYHeGiiynMBgyYQ1yWVqt74wmkDqqzG6mkwAd5J4WqpDzvhpphFLi87
nblQELNT0LW4StCHgPLzSbbtSxb4ZxYi69VpqZGXKdQf9lZaMbUseXubg70D
JX3iV0olaJgABDRCWYRyToVRqAPt0LanidhfIZfiiUps5rEAo/JALXofVwHd
WJ2qsZyDa4eygGdLEbDjdBO1gDX1AnGa5YNFcjOb83FjkrKubqe6U57hYDkg
GQCihVQlFanMPhDSau+LS4VR2VuLCkmnVLPLdEaAg62BiOCh3kktUqmXq9Zo
bz+5aIrIVa8PP7z6gTQvyfb0Vaog/Awo83uob4WeS/3u78DYjdRvObRMPYah
EF5WkJZPskXAJg/wKgt4g7zJlVcQNTNNG3upcS5CxRjv8ogRrtAD8RfFEbw9
QJgZqqvDgCme8niphYkdPiWTfTmxe6CnXYw0TzMfyiAjA+LvpgIEJgyJb0Ld
LA1ERdqYjMrp+eK/Yrgjr83iBQCEee78MVNcXEXZp1ki6jniegvHhaHLldW6
KFlYrZtJPoSUFeT9S5CIer1eaYSOHXoI+NeYH4FwbP96zypC2Wc2HyEJSdk7
2U4yTirt2khJntFnj6XSVwTfnRfKYm/dK7B8RbroFV9fGpHOU0DLZxwr0vnk
I2kiWscfE8EC/JGbnkCBF2usy/A6qf47OX6+wtyAAj0lMCjYJCzVgm+yoBH7
GpXs9ak/AYKnF3WSyDLC+vLggzO4nLQoAhd1ZaH/05D07olIlqlDZUFvBkw4
hfPmMm7Ek+m1dR8sUqZVQF1mndUYc4b9tIitVFjmZKLgmh35lhexVUgFHVSY
7JCDlDvywxUUK3h65Uz1ryQyw+Lh9TIvxHidYYbERvh/Wz1FvvysAdXNrZiF
yqgWLsYpoxHYBuxR3s2GlshxD/0Pc83DLfiwr6KBzLoYJdPRur+Kb13RbvI7
9CZar1PxJfzic9j1bkNPA2ZpbbEwtDB9MOJInjwlyd5EPQLxSMhrvIy0AEKv
1CiQCIJ9/PYYw0afTeG9CD7JSCMyEY1lXvtL9/0Rsy9HcaAxxMigm6t9UjBr
rEVp8H6QrkVOuSxRa/FlDbG1GpoldB7tvFEmDCVXEZXfGWDKBysJMibG0LkD
HoyUTQIZyTQkvO9NY/SiDAsf4jpDxVdVJI16JWczqZqkHPpGqhk9rl0umKQ2
Fpe+Kg+lGOKtlUiU5Ae36+a8HndBUAy1Mris1sYPaC05FCZxq/oosXK1mCGP
Fh9SH60lhJcxNjmpmUDB0Zzjm6HGOiYxI3uP07CMMYt/2k/fIImyhdOc6bqs
P8TOBqhNbT5jAwrGdEWpkV9d4YSXdaUBT9MH48SKyJbmsgmpt/E55Suamz2H
FZWyiWoFpXmVj93vhZucirFJy4CjgtnZLAtM66VLFL5JpnSJuQGaDaubvu/E
6IO5v8pvE0Rh62uCOAiN8NDSylI+6UQfBLhyUeu3j6PeSOyYwiB30VBzIwHF
jWjFqHaccdUxGttsU4icxjCnhmYhErG4Ynw+NmqvaQNGZgK9Qj1aqWtQfvTq
LaK4kjm0sk9j9g+f1zi2eacpCEnU8Sfc3++Dkdvbfr3ncP4JqctFLD2/0kHx
Dyl8kWzGJVi8SeKzJgbu/v+a/BuzKl+eO3WfiwMmEJkhV5wkaDifdIU8hsTR
bkaRfIBQRyXzrLMY3LaNJVOIb/2+9M51s1i3f+eWGKD/4LbYTfRP7Qt+JknM
VQcNt52QsDALb4q2JxVBuT7KSI//fZLlk+vvceH/ykyJUjjfLiMic8Wkhr9H
hgy2C6rpLqSMasq/tMJpuZXXMq8RFrICpu8hxCsfz/AZYWZE4MLoLEqZLSv0
S1BnVebsM19dG3za/Lkv0OZfDjLtvcZCl97iZjqa134ys142Z2Df3tuijIsb
O3JJb+ssgnB1ZRvIaUyN5yHS39cMsh4UoUbMPuqT4ca1D5dauZYxKMl6BxYx
zeSb5f3wsG2qVPpeNnuwz/v8dcGP4A2QGOhgLgpfpqRvVJPGufe5a1kdbwf/
vmrvs3IIzrBFymgizX+ezpiXpfnEhMHz9vfPJ2zl79hiHz745+b8/E32/v1/
dMbXFt4wMSsqE0UFf8pdlxnIFkJCTlw4HPFgF4CWDENf2IujKkNWWa+U9Hjk
aoEqc8itb+mjrrqlm8QJWc4QlZ2rLm6SjZkXH3pL8iTmYRb48rcIrhDZuJ/c
lzpD7L16IhsNZZ8RoO+jkJNctMQ17CMVImxbPLJNZxGHl/ziAYW4hClrhJ3M
oFOXqW8/Yy/9hauCtP3pg/aSq7UynGDhCaa5y7tLxGBo95MnRjv5xkqtLcbw
g/Qr/Ze4kFpjzhLu4JscrIFbmqnkv8cWn0YNAW52lmJhMrLEB9/4aoghORcN
JkoxrIizSmMeJ62VgNe0LlFYjJfGTsdx7+CXkJqK1RndaVEawUQby3lpfTQM
x/ea0CY9JrVyG4lDMoKEPkFTPx8Oy+I9ApEzCIeqjDt0JJBMpqj4C9dCE98v
GCkXV1rk8FU5Q77dcxA971BIAzxyxxCp7xIRRwJFuO+Y17e4LU/aAeJYf0xv
cUDh+KrFhScltlDicKque7iiQ70tfDWEMFTbeE1Jw3CqjbXUlftkcsAjF9m6
b6Is5pZLDiM5yWpFjpYawmEmLpWXa8WcV99VScVZq2vgomLR9FDKElrlGeSp
mM1T8oK0TrnvUIKqvGifNlSmas4mr6iQ7mmSEXjWOwmDyrjVh7DHkVYubOUx
sEqcxbmPBJU0AugzuJFLRVsIn+eTZ70juhuCRaIoNR/XohqyokRS8eMHmC25
X2XmrmIYfGZ41kIt2BPE1D2Ogwt19uQ8Xj+cBqAxZXbEjE8vqj4yeA9OgKZG
WosVSJKIx746lI6BWyIEQUzNxbH/PZ9Lmq6dC6gxy71HvgjDIRzUQo3H41Mw
Xhsrpow6pP1sQrvOXNucvpd/7xwSINBqZmlKOoOBm3t6/sfhz+OoIIreFHYV
l7HrPwH+8C5T9Pm+HSx97ZHRvGnhwlH7ZBEv4ZwuHF8GBPQBvEQQ92WPNCcf
0BryMMEs43H7uK23xjibnpz0/by0sLgIQ71LjDUXNp2Xikn09MVlYJpJYGUC
juRJo9aNBMlGE0oml1/yPF0zOn/dVWbH1XwDzkxMUlrGiITya1FS8UQrFYty
8caP1upXqMxiMaITXjKvw3nbrixBIiid+4VN4mxyhles9VaihegqEupi2W1J
9LKPWY5rvIsMH/Wc0EjNrPltp4GcluwcArtgDknD4bWTjLST6dIQ0NDiQXwH
mXddM1N5E56c/RyVqCep2sLM0s2lobbWNkRjVDjLsLFOh1q99hLlRYN6YA2e
jW4LIHPBJpmjeF7cycxDPj/AS6ZNGy8/SbzlK1lyqkeFpDRv31OjDYtiUvWv
hTLhLvDfz5ESrSICht6XWSidZzRupkUMJJRhvggfGTEbRT6bjef+M44yRtB/
75Ns2n+Xw0yu2H/QYQabsBo+D9KzyqUAPrJCvaoSVTk74ITZiSk53/w2z4VQ
JUb0W8vonkQKHyQe96LQtjRG28qkJl838cUIN7RIZzKnVrlgAQCEJnok4RyK
C7NSCLSk6Y5TOizEVYvCXkZfYY0EMi8usdoY6Oql3SzdLOYygugZKQX+Qmrg
CmZvVW/R5mx6IElcwaXcWHGgRNG06hZIsoZtx48s2s3i1q+7PLcEYrbUsl8j
6oBLNtY7lpa1M18o63pf0RlhtCiB/+/QdSeXZyEuIcRTThCtMoMFIkP+qW54
OebGJ/55mBvfFAZYWiBD2tZ88wh1Kz5F3dznU7c4T0rIl1nspArBI4w2kklL
i1eW9twC1ySqAe7Rh6OEILrZ4OPH9YvyMRV+7std1b5eBIcY030SVI9yGbRs
T+n3kXe5KQ0sQndpkl7Sj2Q9eV5LldLz2kwgEivE9w3HEVZgZXitHi5CCyA4
CYjCBHGBswv44ULASTjGaaIxSausTMIUrWryC/LZxCpJe/vPRqxsy48sOmlT
PSJTTzmOqx8qWt7mqZGp+leTAJhWeWkfA0nRisECUaHNaAfrKF0lK42iaMI4
YCggd0kitHfnfo9oKCvcA2M8jlavF2+087UOD9WOkAo9vy4kn0gBzskdoxJF
2LTBPy5zlBE900hg8GRLpZ7TJI0z0fIC3v4cGg1tKmkEZrC+j3uJZVi1lBqy
ieZi9u3ERgHvi+dhXLYr2teN5l/3Fm+1KWaX0G/uowESdH3auxzhYYaXxU+Q
4RDiaXret1bshWbirr5th7w+brjCoGlXXOmaFmaGVmnFcuQlN9XcxVqkb0Zr
TMiimA22FrUVigQuffBU/Wu18amBeqriOpYmGJbqEAUnJGG89mAGeexhjmg9
LpNhS55JmAxUbBBHy/WXXffzpB3HsUXzRlrSodzRgf94Xh24K6AMFQ8j2WR+
EOW4kvqcIw5kcqkQrG5xnzkKxqqbqSH7Ski2lHeXuOgkq0hC+G1muJmaFp3s
Ksd456v4wCJBuOB/mEdF3fxxJMXC9c59m8A8tQNZfJFkX+oiBt8IUDD6keDX
yK5uRxYfpoa5JQvwrDid1FNEbVkimJ4jhhDw/LYYIEZoJAXkhAGxP6gP+dK2
KKEwaUM/LaDXbrUdR0Y2DK52EgqGqGimh0XYI05PDtaHxKVeuRAaHExiE3cm
jwsMIwnX8qNIMFBoTGGQBvbTEvz6ldxYyAkq6xEQFz6Bk40rLBQFqto0HMD6
VuNGJAnLMtY9xuJihSZ4UPmsE1H4OI5DR4KRwWN6VIkdVYoYezSjoS1gwnbM
ZMAr4SgdU28rDi1dBKicunYNp6pyvCKJucEQPax3AI/6slhawhNjHP1tDQbY
chbGXc3hNxvLiQIxYq7NK0AO/8Dsd/egxW8TxhWgKDXbAj38jWzuF20/y8q1
IWx+L0SlunQ75mqMRJ74xqo/GDzKVS91yyE3KOpqYoetzQR4/xHqnPVhTOF3
+cRPoy9YXpFiQbqvP5WHO+wrsLTap3sd683mUF3g5/bzRBrU2+kPoOXEzUet
VcIi2gLvT051OQ7Y9sHzmyx4HpEGTMD3sh8coxO3vRg3IoXQIyqym0pwK9Bf
FGbsqit2B3c+VxrojHpEpEwwQ4ekJ+MZ/vC0VdoLgI2hu65Etoycm7DHNepQ
VRoTwGtO4eQRKCNEcufYVZ2qgCVdhmGNNM5soAsH5KIyltkcKuQkuBBZo9Se
orPpai2JZgIPbgZNyGlU4gt5x3oaCyWbKgzZ6fnSGSaNQKAI/MUf1tlADPNn
OWgzn17Oy6P9hVOTr0fn9vrjIEvioghCpK0X7EqN4SIGfdbBQSUUFVQMhFzg
TzgTiRL3EelJIsRIyECimE/hzqLdvfSE6wKBimv81dyFSqkniaQnhd8oR45o
4fo2ktlDC06+/BBx1EwxSIM9LhaDIraInY+TE+fSg7y+sD4ldCFNIOomuuYY
0sbFdQTS1HfzMwlRuais6sUwRcgOQIJV7cwSM04Pw2jJIR9JSgPgAimVljlX
BdafkCJ7RKs8G1Q7ZON7GoMCTYR6Z6yG3ZW+qzOPGjGdb+yBE/vSJUEsF/PZ
SGZlPxeGs5p21cIkLOqpFG9kVF4Wl+n/Mq13rXc0lz5EMsm9ahwao9oZ8u1t
xLghker1ie5oO8pVAdAjLoKAW468YvgWy0S+1nQ8tSpveADS4flmsIhFApYs
KfRlbornL1+oLW5GSNn6MGBBmnSbc+Tv15Kj0ZeqssophsN7RT/+M+fmAlDU
TzFtHVSa/X2bCAocJxjoHyweFnKIcAQWSg1CQp28e0DJqJV5JwApXsTCeWyd
maF+cXsn4koqgXJTRD74ErTu7O0IdLWO5W3w0nhdqEQt8LaRukKVkWIW8dJ7
4uXOGzEbBE3c8nQ1hVWrSLMWL0hLBPVQs1HZTyth815hiIUuV0/0nVVlNZ42
lNWRtL9I3Mc6MsXZWypYDoeBAdk5UvjOFyeTAl7+ZMLX4/J7UstcsiGVWUl2
Z+rp8QfItiwf52/h5o3lEeeO83s2+TZqZiKW7ql0mxj5/QIdDAe2EI54QOMO
Jm8+7BG6dGtt5JcuhC9oQbO6ic7f2xaYi56bSePUXMg1ivBcDa1mqwao3Wt4
oHLfULLXlUOMt2h/PXjPXhYTE9Vfjp3xcVUej5u/QHXzEnGgI8arUWpd1qMp
2AEpfW3WSlqb7KJmYTn5raPGZqYvsknKBpPucaaQeUkh0h7hDqNPablM19jx
6cMGN5p1oY0hUt0J2owTisj1f0CscnT3qboS+5EZGCUS4txYaOxhokSQ2I5F
lVc7strZMiOz7+GXdIJwKiqfTiBTPZuJ+a8qr5+RF7LVuWbipqw+srHLCslH
s3Jld213JDEkcSdF/tg31ZTWgzTYPHU3+8wOxr2xFeSDOGloGqT/Sz0WWC20
ox/TuXMjLfugTQvdHe/FBXM470ZbPYUSzY/Ha8yzivZWN99ksNigPzW7CBdK
WYRTHZNC8bH/hkFOWu5G6ymDF02NacWwf6NIM2VQ/0QuPGg6Q1WLyE21sCFC
se44FS2PUMxSudh8GNeAT+A5d5NW95lJBcKoLhq1Bfy2Ul34fcUpUDw8cpu4
vD0Syhfhie+GFFejvOT+TRy0aeuSCc3ehfjiAveKk0m5xg3MTmUUaRmmm8zo
U8fDdHGUOLPgkfIJF07Yol2ix8gL4IWXjXbsnKhavEyANFkUs46Cb766Vr9h
751f4zw9v5hzc2E57vJyHBuGWxIHjj2aZiPv5gOLM1Z1ybnXx4r4sVX1tJad
r37+wKkSPPJWyxCFh+eTCCtwubrmfFxV8CeEik8n1owGsdxJpIvY4somb8pM
Wj1Km6j12PeZ1XYw1iwZ5dpDl2DUCWXdHEE0bLEDW6WXXHiJuaz4To3qs6rK
4+5LTukh0Q9Liyol0rafcvGEAU0GIg+fmJ2cNBri2ydp78bXwNArbiFQEyjV
deXxydTyG6I9DcnPZajVAI/UV9f0rxxTeJLkzIu/0BnzEf/V2dmvK/hDeqIN
Cx+CBDOKkpoeSadYnciHrMmaGcZZfGiKM36aoKJJbPEDMsn7oRW+mHvTs+0i
OYXWoz2yB7aeXBGl8ylUeYVAYJM56thChAa3yPZYaOJKXG4iKe3o4bkQl7pV
JUAF3Ho8l1j70JRL3OGrmiQ0IthMjirfiC/sKVoPX6RXnLwipjFuKC0we/H7
3/3Vimm+dFfFb+mt3xIRd0VxVXyAN0jwKuIUGxKu1tia6BWkX5GofYYXyNgC
AQZVyrRzc9Q+Nkw7C31Gni+fE+Gn6d9n069Z+jBNBBfBFiSr6B9dBpYAPq1O
yEqizKVM/2eu7MU8QbBQC7GUG07rOp/U7dcEu5a2gpdVlZZv43T5kK7RQH0h
YQ0iuvqyvtGaX3HL+dZ+wzcOJn7sn8PItKUFEQ3EPMQ0MUwnvE4bYXqXZhle
JeTbdeXRRQRQSGJfzPTI0eqJdkVbk+FobSTldeemCe5ebnvB8QTdBsOiv5Lo
cifuUxJ27ntWS5OM0BRcK3rkI4WmL+pqVWFFbINYfO95bD4Zh01qfloUUfKk
Qc3wJ9HFQHxlpf0tZB4oklekqTEjJVWGwyOk/uei0EH7s8rqrZPGdVodivRE
uubsRpaUNbMmj2ABSmL1QJw/lAi0Xp0WuHDmG/9DQcI3g6fSwhqu4k4uonaJ
/MtGjFoGe4VO7QAYzE0qf/psjG9//FlqRkmftb71+MtZb3gSTNTGo3oCIQzn
82XxjXqznCzJWs2W4rxm3/gZsdllT0yCNX8mVeV58GU8CBm4xaW0dtdRhLJr
BlSoxnSR/S2LX7ROl5QscSLqM4kRUP1WccL3nq8+7usVO0EOZ/bUS9vgqMAr
qU7VYbsotHUse51Dy24HZfkJsxoRWdvuQIhlBdFC9ES4X+gJhiRCCaQBu1bT
MUiJJlJyg0uSREjy9AzETHQ+NUwUYACTWSQKOxX7hxPjkzSD6teEwB2H2EiY
IR9DQB4PFYZ/hD2EZnxWnnEJ1PvUfC2WFTY296EEIDMZjIiDYC7/WwG7UjKO
bNyLcHUn7ijYv5kDhRMghPgtmAmJe2cOFvHrFP0fZdcgqB1sF/GJpaSO7fAH
HkQWgjTZ6O3fakmLJq2tjB0wL/Kfs0A82Tycrhocf9YrFfDkLn+V2JzFR8y+
BZh37+sDmwKK8C4srv75Kq6SKob+baivWat+pVYUnD+tKAcBjsaSsmIPLSlh
SeyYVhpTrpP2KUS+ZS1lvaT0xtBx9Den7ccqnD4wtS2A2WAnWoNYT6pGNWI5
DtyN6DRwO6JmAkmxQ18S10/Dn08tRYMiEYrdlZwPIodD97OvcnFZbRvynkZ3
ohRhAsU3kXUS3Jk/XBG93x9LYe3EYzhuVxN2y/rIFji7VPKlKovh3oE38D+T
qJtvzppYrHGmRDRZkzKbqZXaDcn6/ILG6FrjRjprIuVax8vi+ep+n0+e37wl
yo2zKWZR+JQ1aeSMqOgr4H13BpHisfZq0uOBJDLBxXhE93s4VE21vhWQPXll
8+dX8YnVh9IoEisDGF7Wox7V4DbULGY3prPSw6hM8pLbEo86WwtHgr9lgDYk
MLWWQWWjjcA5sEU1RuIw8+Ib7accbAgiEkzuyoHLICiz/rXyJZLZjkVbmYC+
XVfrqQVDtRbH8wAMossT5i2sOUPt6BF/yZzp74KcuRXQCY7O1avKLvdYcrxj
pLOoRTJTqeKCNHQPNJ6P9ClursdByb622oTMikUyTeZ9Qs5e2J2qiPC3D06D
Xmr0BFy3uyYExsadPzyi+6yL9t737WLV181Q1K2Cojx/7AiHyGSAWrm91DaV
Hq9osN0mXApxqtzOxpq78gq+hU9Wf5nWX60xZavdcCa08+LGIhQsQGRUD3yh
jjxNVfRRlxuYVTtd2EETasyPvkwbuZxaONniTVh8tpiguZ0wFHmuG0wvu3W8
P5WYAtwSWjlUJLeLvm2NOCHmsvzALA+1f/2nU/XOA/Sip5FdhhSYr657y6Um
Gjm0BxK/G1FileGFmhMcwNrpDYvC+PVq+nLsE4wnu1MuUKMbrRJjPA9SlFgt
u9JnZAKTYgMjc3g34lFyBQXPo/1mx8Pn4KvVxs+MSNQWfiT/hE6ppfB8az8I
qxviRlp6S6K/tRVIL5hjPDlOuXnQ2FNYklG0w/w3T8KaWTouIs2a7hCHB9zE
cSJe6Jr5+zjHDfKwV1lGSEq6Vefp9zDNPmJJQRuTckUEFtIOqo6ojHGJ1MoU
++pwkvvgy0ROwlxiDTi0HS1D0ceDu4iKhYemmkRlOQtxkinB7bPxlSom3e2Y
aWKzviSiqZGJEN3IEqSRKXJ8tJyvhms+sBIaMCJ4VVlGXRSh5aGofKznQP7o
VfE0Uz6ye0lK3nAVMzYoYNNz0fGM33OEDrxGT3yRxiegC6EPsKSpRJfTW8gM
k6EAAUPpFxKCuNSsEOKomTkO6vu2ufrfXMuAW+4JIeGW5qkF6F/mUbuZqBm6
NBMQZ1HUZ5cLdqi/vfHeU7OLabUY2KW4ZHPXIsBTe5aJmYWWqlaMhvfblw86
1fuaSRZumcRuSK+/UOaQpVS8iX5qPRuWjoCsEOeItNBUB/atQYvFJ/cSAeqD
N7QakJSDJzgO7bo9yHVg02zL5fj4OxGSpbcgP2UXqQUQnMvQg5iXJCbB0tI3
w5ZF8Tmf+MizeBwp0AUteYJtkFAwHDQ2mAs4s6PFzaS5auyDictIS0LBk5h2
0pKecFGVqMd52UmBn5cgMF2TwIDZxxDzDCU/f3BKyAkI5YYB3DOlYc0Y+Ki1
GuNG23EhwT+4IA52Is+jV/2566VanuVe6XY8cYyZDs6b2C9RUyQ60KW8Z2gT
jt1W1SlE/njgrKqDnhnD5w+cvRo0A4D2SY38sVdM+GptGmaShfhrhxAXljWr
cD8lnSnh49Qe96B/mgVrloOozzx3bQFK4MjseGUG6VgutAAm/kzaFHizLf9q
S/p3A5/7JHVVxcreKqyRrTTURDwtD213w9O/zM2n8hBzAk24kxLSRnBTTUiY
laQimwSCAYWZLlVklEg9elSefFsEX8YtBci0X7BHd6A1fLueA6oaL6FlhnFa
JENbIWWSjI/YIYVKWs+3G3Qg2FcT/qGQ9BiHUcED1XC8i7mNJYcbGY9iT7cd
XfkjFqtHSLPEJ+1Kojs0MMC3c8gOxzdtWbg9FAHctwij/NsRRnlbZcSyUd1Z
TUnMRaXE8U8q9mj+SbAETihBdPfUx6fCldRcZsUj0vbjrmsW/NzV/S1fFXqd
+0SKoawOq+E2T87cU7mGxrzpdGDpPBxOg8Lhfrg+HsxWIGaHcFuQ7FKUK66V
IZYHlTK3E1/HRkHOJUZGbR/3aJIc29r3VylefKlGSS7plvfN8e09a8QFSS8u
bvPizHvo5U10eY3Wc68FSrCcUD7Qwv/idqgf9j4jdry8r5ZfWBMG2lB/XsOA
S9JSQFYrqYK1ageidLne2SlmcOba2edOzt1oaihskmwqvSRmk3otUTa9Bem8
dO7KZ4eN2qfO8CfnSQXFKoHI3Ev1hdi+Rn7yuLdzMpMJDv/YPMbhJmaBwYEu
JRoKXbYzFD4tYlOtmXj6+CF45isXiY55g9Azfksu19K9yht1B9Yh6ouIjEyS
w5XJOmOto/JAIlSXxbmp6XitLB+bwmEMmV6Ee7uppJZXZpnKwlfKUEtLpFAY
1XdVw3SdrU6xhSBmq4JO6ACmxYUtLFM0DbvzVbNnjgC9WjpMo5QIfCVwOPuE
N2YDUKSjYs1aHpldeYc7VXvdaLNMfYg61eooinbINHHXSbU7K12Ouveh2RkA
WblHCJOn8dyVo2piSl/8SSUh/U3dUZtNx+U0NxBNo56CUZBP3Fko7o4TuoGw
T0YqdhZTcs3VI2w8scdYaMhUGJBu8WloRug0r0HFznA9EzENHbGyutgqVNcw
tJvBJDp+CYqM+t4kMBALuZdRxjFY1p2dpaaohWFYbjB1xK0VP8D+zAa8Pq2z
YA0qUGxGDPKEN1If+5u6YXVCe5xhY2iy/ueq850BsJ2Idtvt/vr6+stIIfxq
+WIulap8zzt+8cP7D9fXX0fvPX+x/GL5hUVSwkTGEYujMJys+aS1BBwkgL9r
N2dpkDLZxqz4jqVqEeGgf0VBuuBFPjgFMex548WFz0hCEhh2deT2ikgikJiE
ZhyXzpUdNEBTmHtceYzW/gRtJbo7WBSeSFStkTc3O7WDNV+Zp5zNBBexCCgj
Mzzw1jxnGupkmOFEv2pWD5LqPPzxuZFgO0920awrtHNO2zM7zcQ2t/5gZZWi
ahZxWoWEKGs/wBCHnSYrq6k3FMaTBRgN8Rd4JnQkjomPeKzEHkuOQ5TNgNBX
n8amIYwPsDcClEgilIyLPBKRyXrqXLSCdlv18kgqBBqvl2byZY4RaaFBp3yk
nyNTLC2w9lbOScLxx1GZF4pISIZSxnRI30FGfoaGHgN99OuYyZKgf/P9DUfY
woYmwiEnxVp/eUgA/A5efk8ifcdMMf/gm9hSgUwK8TKhP2toLaTO2OqopdzU
5TK0bqjW+6Y9tLuHKPJPmkcJlydV/BkfhqCED9TeaMBRLbagA8nstKi2Y759
V3dto24kpoBE46SPs/E3uvYs+VoIjXj3SiS6J8ROBCgL3Vm1d1ZMJDHQWEjG
0J5kI8GZFrdpiYOo2NHvA67Fltn4WtI+4GtfSokV64hgYZQcr8fhjEitcVDg
lHj6taDaRk/owyYofVsNvBhBor6hi+kn7O49d8y/F+n2au8XqrRFxpMVEcPb
q1X78QlbZup+gfKDEhtykEKEsXO3T4I2fNxYay7UZxKN9F774a7Lk1AERqT3
f/rh5+9eAU4S5G4dLBUtTOCCs5gdoMnaT+eOpDvC+EJ9eAffRAcSiUKrN/Qu
JerU+fAlm0aXwXoXnyXiTHQlhHpSkKOJDsLC3+Su3ax9P2XAg0QQ9P2hm3oL
Af7mUK1JIgMVJ6z/4cfv3/y5oP9iMzwsYq6EH7QgCo4zP6p7sY+cjyR5nL1x
UhueSkSvutfU0Xp1dUVHtr51/w/Xhxr0tdkAAA==

-->

</rfc>

