Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756195Ab3DZW7q (ORCPT ); Fri, 26 Apr 2013 18:59:46 -0400 Received: from mail-pd0-f173.google.com ([209.85.192.173]:63227 "EHLO mail-pd0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754896Ab3DZW7p (ORCPT ); Fri, 26 Apr 2013 18:59:45 -0400 Message-ID: <1367017182.8964.258.camel@edumazet-glaptop> Subject: Re: [PATCH] net/openvswitch: replace memcmp() with specialized comparator From: Eric Dumazet To: Peter Klausler Cc: Jesse Gross , "David S. Miller" , dev@openvswitch.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Date: Fri, 26 Apr 2013 15:59:42 -0700 In-Reply-To: <1367012792-25335-1-git-send-email-pmk@google.com> References: <1367012792-25335-1-git-send-email-pmk@google.com> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.2.3-0ubuntu6 Content-Transfer-Encoding: 7bit Mime-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3022 Lines: 80 On Fri, 2013-04-26 at 17:46 -0400, Peter Klausler wrote: > Tune flow table lookup in net/openvswitch, replacing a call to > the slow-but-safe memcmp() in lib/string.c with a key comparator > routine that presumes most comparisons will succeed. Besides > avoiding an early-exit test on each iteration, it also compares > keys 4 or 8 bytes at a time on architectures that can load an > unaligned long efficiently. > > On a 3.2GHz Xeon (5679) this patch reduces the minimum back-to-back > hot-cache latency of a 128-byte key comparison by 7x, from 130ns with > the default byte-at-a-time memcmp() in lib/string.c down to 17ns. > > More important, replacing the default memcmp() with this specialized > routine speeds up openvswitch's packet rate by 10% in a closed-loop > benchmark that simply routes traffic from one tap device to another. > > Signed-off-by: Peter Klausler > --- > net/openvswitch/flow.c | 33 ++++++++++++++++++++++++++++++++- > 1 file changed, 32 insertions(+), 1 deletion(-) > > diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c > index 67a2b78..d5facf6 100644 > --- a/net/openvswitch/flow.c > +++ b/net/openvswitch/flow.c > @@ -764,6 +764,37 @@ u32 ovs_flow_hash(const struct sw_flow_key *key, int key_len) > return jhash2((u32 *)key, DIV_ROUND_UP(key_len, sizeof(u32)), 0); > } > > +/* > + * Key comparison routine, optimized for the common case of > + * equality due to low average hash collision frequency > + * (1.5 mean items per nonempty bucket when total table item > + * count equals the number of buckets, which is when openvswitch > + * expands its hash table). > + */ > +static bool equal_keys(const struct sw_flow_key *key1, > + const struct sw_flow_key *key2, > + size_t key_len) > +{ > + const char *cp1 = (const char *)key1; > + const char *cp2 = (const char *)key2; > + long diffs = 0; > + > +#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS > + { > + const long *lp1 = (const long *)cp1; > + const long *lp2 = (const long *)cp2; > + for (; key_len >= sizeof(long); key_len -= sizeof(long)) > + diffs |= *lp1++ ^ *lp2++; > + cp1 = (const char *)lp1; > + cp2 = (const char *)lp2; > + } > +#endif This seems a suboptimal condition, a bit tweaked for x86 Some 32bit arches do not have CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS, still struct sw_flow_key is 32bit word aligned. Either its a generic bcmp(s1,s2,len) function without any information on s1/s2 alignment, and it should not a private ovs thing, or its OVS private helper, and you can make sure alignof(struct sw_flow_key) == alignof(unsigned long) and remove the #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS Check include/net/flow.h for an example struct flowi4 { ... } __attribute__((__aligned__(BITS_PER_LONG/8))); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/