]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
OPTIM: ebtree: make ebmb_insert_prefix() keep a copy the new node's pfx
authorWilly Tarreau <w@1wt.eu>
Tue, 15 Nov 2022 07:08:24 +0000 (08:08 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 15 Nov 2022 08:37:09 +0000 (09:37 +0100)
looking at a perf profile while loading a conf with a huge map, it
appeared that there was a hot spot on the access to the new node's
prefix, which is unexpectedly being reloaded for each visited node
during the tree descent. Better keep a copy of it because with large
trees that don't fit into the L3 cache the memory bandwidth is scarce.
Doing so reduces the load time from 8.0 to 7.5 seconds.

include/import/ebmbtree.h

index b2dd1447a88774252d502b9b3755e89d3cca12fd..fc6a5002ee69ff11a3c66b53e925423b9c886417 100644 (file)
@@ -618,6 +618,8 @@ __ebmb_insert_prefix(struct eb_root *root, struct ebmb_node *new, unsigned int l
        eb_troot_t *new_left, *new_rght;
        eb_troot_t *new_leaf;
        int old_node_bit;
+       unsigned int npfx = new->node.pfx;
+       unsigned int npfx1 = npfx << 1;
 
        side = EB_LEFT;
        troot = root->b[EB_LEFT];
@@ -631,8 +633,8 @@ __ebmb_insert_prefix(struct eb_root *root, struct ebmb_node *new, unsigned int l
        }
 
        len <<= 3;
-       if (len > new->node.pfx)
-               len = new->node.pfx;
+       if (len > npfx)
+               len = npfx;
 
        /* The tree descent is fairly easy :
         *  - first, check if we have reached a leaf node
@@ -690,11 +692,11 @@ __ebmb_insert_prefix(struct eb_root *root, struct ebmb_node *new, unsigned int l
                 * we visit, otherwise we have to stop going down. The following
                 * test is able to stop before both normal and cover nodes.
                 */
-               if (bit >= (new->node.pfx << 1) && (new->node.pfx << 1) < old_node_bit) {
+               if (bit >= npfx1 && npfx1 < old_node_bit) {
                        /* insert cover node here on the left */
                        new->node.node_p = old->node.node_p;
                        up_ptr = &old->node.node_p;
-                       new->node.bit = new->node.pfx << 1;
+                       new->node.bit = npfx1;
                        diff = -1;
                        goto insert_above;
                }
@@ -718,7 +720,7 @@ __ebmb_insert_prefix(struct eb_root *root, struct ebmb_node *new, unsigned int l
                         * the left. For that, we go down on the left and the leaf detection
                         * code will finish the job.
                         */
-                       if ((new->node.pfx << 1) == old_node_bit) {
+                       if (npfx1 == old_node_bit) {
                                root = &old->node.branches;
                                side = EB_LEFT;
                                troot = root->b[side];
@@ -774,8 +776,8 @@ __ebmb_insert_prefix(struct eb_root *root, struct ebmb_node *new, unsigned int l
        /* first we want to ensure that we compare the correct bit, which means
         * the largest common to both nodes.
         */
-       if (bit > new->node.pfx)
-               bit = new->node.pfx;
+       if (bit > npfx)
+               bit = npfx;
        if (bit > old->node.pfx)
                bit = old->node.pfx;
 
@@ -786,7 +788,7 @@ __ebmb_insert_prefix(struct eb_root *root, struct ebmb_node *new, unsigned int l
         * node insertion.
         */
        diff = 0;
-       if (bit < old->node.pfx && bit < new->node.pfx)
+       if (bit < old->node.pfx && bit < npfx)
                diff = cmp_bits(new->key, old->key, bit);
 
        if (diff == 0) {
@@ -796,7 +798,7 @@ __ebmb_insert_prefix(struct eb_root *root, struct ebmb_node *new, unsigned int l
                 * on the right.
                 */
                new->node.bit--; /* anticipate cover node insertion */
-               if (new->node.pfx == old->node.pfx) {
+               if (npfx == old->node.pfx) {
                        new->node.bit = -1; /* mark as new dup tree, just in case */
 
                        if (unlikely(eb_gettag(root_right))) {
@@ -815,7 +817,7 @@ __ebmb_insert_prefix(struct eb_root *root, struct ebmb_node *new, unsigned int l
                        /* otherwise fall through to insert first duplicate */
                }
                /* otherwise we just rely on the tests below to select the right side */
-               else if (new->node.pfx < old->node.pfx)
+               else if (npfx < old->node.pfx)
                        diff = -1; /* force insertion to left side */
        }