net: speedup ethernet address comparison with bitops
authorStephen Hemminger <stephen@networkplumber.org>
Fri, 5 Jul 2019 17:16:19 +0000 (10:16 -0700)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 8 Jul 2019 19:26:52 +0000 (21:26 +0200)
Using bit operations like or and xor is faster than a loop
on all architectures. Really just explicit unrolling.

Similar cast to uint16 unaligned is already done in
other functions here.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
lib/librte_net/rte_ether.h

index c4ff4cd..8ac1afe 100644 (file)
@@ -81,11 +81,10 @@ struct rte_ether_addr {
 static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
                                     const struct rte_ether_addr *ea2)
 {
-       int i;
-       for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-               if (ea1->addr_bytes[i] != ea2->addr_bytes[i])
-                       return 0;
-       return 1;
+       const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
+       const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
+
+       return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
 }
 
 /**
@@ -100,11 +99,9 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
  */
 static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
 {
-       int i;
-       for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-               if (ea->addr_bytes[i] != 0x00)
-                       return 0;
-       return 1;
+       const unaligned_uint16_t *w = (const uint16_t *)ea;
+
+       return (w[0] | w[1] | w[2]) == 0;
 }
 
 /**