Read the four tbl24 entries before resolving any of them, as the SSE
and NEON versions do. On an in-order core the cache misses then
overlap instead of being served one after another.

Signed-off-by: Sun Yuechi <[email protected]>
---
 lib/lpm/rte_lpm_scalar.h | 40 +++++++++++++++++++++++++++++-----------
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/lib/lpm/rte_lpm_scalar.h b/lib/lpm/rte_lpm_scalar.h
index df4f83fa48..9ad25838fd 100644
--- a/lib/lpm/rte_lpm_scalar.h
+++ b/lib/lpm/rte_lpm_scalar.h
@@ -13,22 +13,40 @@
 extern "C" {
 #endif
 
+static inline uint32_t
+__rte_lpm_lookupx4_hop(const struct rte_lpm *lpm, uint32_t tbl_entry,
+               uint32_t ip, uint32_t defv)
+{
+       if (unlikely((tbl_entry & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
+                       RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
+               const uint32_t *tbl8 = (const uint32_t *)lpm->tbl8;
+
+               tbl_entry = tbl8[(uint8_t)ip + (tbl_entry & 0x00FFFFFF) *
+                               RTE_LPM_TBL8_GROUP_NUM_ENTRIES];
+       }
+
+       return (tbl_entry & RTE_LPM_LOOKUP_SUCCESS) ?
+               (tbl_entry & 0x00FFFFFF) : defv;
+}
+
 static inline void
 rte_lpm_lookupx4(const struct rte_lpm *lpm, xmm_t ip, uint32_t hop[4],
                uint32_t defv)
 {
        rte_xmm_t xip = { .x = ip };
-       uint32_t nh;
-       int ret;
-
-       ret = rte_lpm_lookup(lpm, xip.u32[0], &nh);
-       hop[0] = (ret == 0) ? nh : defv;
-       ret = rte_lpm_lookup(lpm, xip.u32[1], &nh);
-       hop[1] = (ret == 0) ? nh : defv;
-       ret = rte_lpm_lookup(lpm, xip.u32[2], &nh);
-       hop[2] = (ret == 0) ? nh : defv;
-       ret = rte_lpm_lookup(lpm, xip.u32[3], &nh);
-       hop[3] = (ret == 0) ? nh : defv;
+       const uint32_t *tbl24 = (const uint32_t *)lpm->tbl24;
+       uint32_t tbl0, tbl1, tbl2, tbl3;
+
+       /* Issue the four tbl24 loads before any entry is examined. */
+       tbl0 = tbl24[xip.u32[0] >> 8];
+       tbl1 = tbl24[xip.u32[1] >> 8];
+       tbl2 = tbl24[xip.u32[2] >> 8];
+       tbl3 = tbl24[xip.u32[3] >> 8];
+
+       hop[0] = __rte_lpm_lookupx4_hop(lpm, tbl0, xip.u32[0], defv);
+       hop[1] = __rte_lpm_lookupx4_hop(lpm, tbl1, xip.u32[1], defv);
+       hop[2] = __rte_lpm_lookupx4_hop(lpm, tbl2, xip.u32[2], defv);
+       hop[3] = __rte_lpm_lookupx4_hop(lpm, tbl3, xip.u32[3], defv);
 }
 
 #ifdef __cplusplus
-- 
2.56.0

Reply via email to