Flow ID, LACP, and igb

Alan Somers asomers at freebsd.org
Fri Aug 30 23:24:52 UTC 2013


On Thu, Aug 29, 2013 at 3:40 PM, T.C. Gubatayao
<tgubatayao at barracuda.com> wrote:
> On Aug 29, 2013, at 4:21 PM, Alan Somers <asomers at freebsd.org> wrote:
>
>> They're faster, but even with this change, jenkins_hash is still 6 times
>> slower than FNV hash.
>
> Actually, I think your test isn't accurately simulating memory access, which
> might be skewing the results.
>
> For example, from net/if_lagg.c:
>
>                 p = hash32_buf(&eh->ether_shost, ETHER_ADDR_LEN, p);
>                 p = hash32_buf(&eh->ether_dhost, ETHER_ADDR_LEN, p);
>
> These two calls can't both be aligned, since ETHER_ADDR_LEN is 6 octets.  The
> same is true for the other hashed fields in the IP and TCP/UDP headers.
> Assuming the mbuf data pointer is aligned, the IP addresses and ports are both
> on 2-byte alignments (without VLAN or IP options).  In your test, they're all
> aligned and in the same cache line.
>
> When I modify the test to simulate an mbuf, lookup3 beats FNV and hash32, and
> SipHash is only 2-3 times slower.


Indeed, in your latest version FNV and hash32 are significantly slower.  It
isn't due to alignment issues though; those hashes don't care about alignment
because they access data 8 bits at a time.  The problem was that Clang was too
smart for me.  In my version, Clang was computing FNV hash and hash32 entirely
at compile time.  All the functions did at runtime was return the correct
answer.  Your mbuf simulation defeats that optimization.

I think that your latest version is fairly accurate, and it shows that Jenkins
is the fastest when compiled with Clang and when all three layers are hashed.
However, FNV is faster when compiled with GCC, or when only one or two layers
are hashed.  In any case, the difference between FNV and Jenkins is about
4ns/packet, which is about as significant as whether to paint the roof cyan or
aquamarine.  As far as I'm concerned, FNV still has two major advantages: it's
available in stable/9, and it's a drop-in replacement for hash32.  Using
Jenkins would require refactoring lagg_hashmbuf to copy the hashable fields
into a stack buffer.  I'm loath to do that, because then I would have to test
lagg_hashmbuf with IPv6 and VLAN packets.  My network isn't currently setup for
those.  Using FNV is a simple enough change that I would feel comfortable
committing it without testing VLANs and IPv6.

We have a three day weekend in my country, but hopefully I'll be able to wrap
up my testing on Tuesday.


>
>> Also, your technique of copying the hashable fields into a separate buffer
>> would need modification to work with different types of packet and different
>> LAGG_F_HASH[234] flags.  Because different packets have different hashable
>> fields, struct key would need to be expanded to include the vlan tag, IPV6
>> addresses, and IPv6 flowid.  lagg_hashmbuf would then have to zero the unused
>> fields.
>
> Agreed, but this is relatively simple with a buffer on the stack, and does not
> require zeroes or padding.  See my modified test, attached.
>
> T.C.


More information about the freebsd-net mailing list