Make comparison done after matching hash values faster by optimizing for the expected success.
Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> --- lib/classifier.c | 2 +- lib/match.c | 22 ++++++++++++++++++++++ lib/match.h | 2 ++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/classifier.c b/lib/classifier.c index 5587141..36e19a5 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -781,7 +781,7 @@ find_match(const struct cls_subtable *subtable, const struct flow *flow) struct cls_rule *rule; HMAP_FOR_EACH_WITH_HASH (rule, hmap_node, hash, &subtable->rules) { - if (minimatch_matches_flow(&rule->match, flow)) { + if (minimatch_matches_flow_likely(&rule->match, flow)) { return rule; } } diff --git a/lib/match.c b/lib/match.c index 35356c1..78399a4 100644 --- a/lib/match.c +++ b/lib/match.c @@ -1184,6 +1184,28 @@ minimatch_matches_flow(const struct minimatch *match, return true; } +/* Returns true if 'target' satisifies 'match', that is, if each bit for which + * 'match' specifies a particular value has the correct value in 'target'. + * + * This function is equivalent to miniflow_equal_flow_in_minimask(&match->flow, + * target, &match->mask) but it is faster because of the invariant that + * match->flow.map and match->mask.map are the same. */ +bool +minimatch_matches_flow_likely(const struct minimatch *match, + const struct flow *target) +{ + const uint32_t *target_u32 = (const uint32_t *) target; + const uint32_t *flowp = match->flow.values; + const uint32_t *maskp = match->mask.masks.values; + uint64_t map; + uint32_t diff = 0; + + for (map = match->flow.map; map; map = zero_rightmost_1bit(map)) { + diff |= (*flowp++ ^ target_u32[raw_ctz64(map)]) & *maskp++; + } + return !diff; +} + /* Appends a string representation of 'match' to 's'. If 'priority' is * different from OFP_DEFAULT_PRIORITY, includes it in 's'. */ void diff --git a/lib/match.h b/lib/match.h index 1e938a1..b310820 100644 --- a/lib/match.h +++ b/lib/match.h @@ -158,6 +158,8 @@ bool minimatch_equal(const struct minimatch *a, const struct minimatch *b); uint32_t minimatch_hash(const struct minimatch *, uint32_t basis); bool minimatch_matches_flow(const struct minimatch *, const struct flow *); +bool minimatch_matches_flow_likely(const struct minimatch *, + const struct flow *); void minimatch_format(const struct minimatch *, struct ds *, unsigned int priority); -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev