Splay Tree

2006-10-29 Thread Ian Blanes


Could this patch be applied now?
http://gcc.gnu.org/ml/gcc/2006-07/msg00210.html

Discussion starts here:
http://gcc.gnu.org/ml/gcc/2006-07/msg00147.html (benchmarks are wrong)

Original patch posted by Brian Makin here:
http://gcc.gnu.org/ml/gcc-patches/2005-10/msg00762.html

Quote:

I've been recently looking at the splay tree implementation. I've noticed 
that this revision http://gcc.gnu.org/viewcvs?view=rev&revision=106584
does a strange splaying. It does a bottom up splaying but starting at the 
root (not the same that top down). It works but performs worst. One 
example of this is that while in the implementation described in 
http://www.cs.cmu.edu/~sleator/papers/self-adjusting.pdf the root node 
ends at most two levels down, in the current implementation it can end at 
an arbiratry depth (example attached). So the property of keeping recently 
used nodes up doesn't work.


ian


Re: Splay Tree

2006-11-03 Thread Ian Blanes


The original author of this patch said he sent his copyright assignment. I 
only did minor modification to his work so I don't I think I should send 
it too.

http://gcc.gnu.org/ml/gcc-patches/2005-10/msg00833.html

I already did a bootstrap and check to be sure it worked right when I 
first sent my modifications. But now I did it against current head and I 
get this:


# diff summary-log-normal summary-log-patched
108,110d107
< FAIL: PR27908 execution - source compiled test
< FAIL: PR27908 -O3 execution - bytecode->native test
< FAIL: SyncTest execution - gij test
114,115c111
< # of expected passes  7000
< # of unexpected failures  3
---

# of expected passes  7006

117c113
< # of untested testcases   11
---

# of untested testcases   8


# diff summary-log-normal2  summary-log-patched
100d99
< FAIL: libgomp.fortran/omp_parse3.f90  -O0  execution test
104,105c103
< # of expected passes  1543
< # of unexpected failures  1
---

# of expected passes  1544

110,111d107
< FAIL: SyncTest execution - gij test
< FAIL: SyncTest execution - gij test
115,116c111
< # of expected passes  7002
< # of unexpected failures  2
---

# of expected passes  7006

118c113
< # of untested testcases   10
---

# of untested testcases   8


Results are better with this patch, but I dont think the improving its 
related.


On Mon, 30 Oct 2006, DJ Delorie wrote:




Could this patch be applied now?
http://gcc.gnu.org/ml/gcc/2006-07/msg00210.html


Assuming it's been bootstrapped with no regressions, and the legal
paperwork is in place, yes.



Re: Splay Tree

2006-07-11 Thread Ian Blanes


On Sun, 9 Jul 2006, Roger Sayle wrote:

Interesting.  Richard Guenther's post for the above change, which was
based upon a previous proposal by Brian Makin, suggested that this
patch reduced the compile-time of his tramp3d benchmark by 1%.
http://gcc.gnu.org/ml/gcc-patches/2005-11/msg00294.html


I realized that 3 orders of magnitude of diference wasn't a very realistic 
benchmark. So I reviewed it. I found that I forgot some profiling code 
that was biasing the result of the revision 106584, and that the pice 
of splay tree usage used to perform the benchmark wasn't so representative 
of the whole bootstrap. So the previous benchmark wasn't accurate at all.


That said, I rebuild a benchmark this time with full traces of splay tree 
usage during tramp3d (380mb) compilation and gcc bootstraping(1gb).
And I did the benchmarking again. This time with the original code, with 
the revision 106584 code and with the proposed by Brian Makin (with a 
few changes). Thus I have been able to reproduce the speed improvement 
with the Richard Guenther's patch.


I also noticed that the code sent by Brian Makin is slightly better than 
Revision 106584 and that not pushes down the root node more than 2 levels,

which can prevent that some rare cases perform bad.

bootstrap

Original
real 61.630s
user 61.010s
sys   0.620s

Revision 106584
real 59.660s
user 59.000s
sys   0.660s

New
real 58.910s
user 58.240s
sys   0.670s

tramp3d

Original
real 26.680s
user 26.350s
sys   0.340s

Revision 106584
real 26.010s
user 25.660s
sys   0.340s

New
real 25.700s
user 25.340s
sys   0.360s

ian--- splay-tree.c2006-07-11 15:36:50.0 +0200
+++ splay-tree.nrn.c2006-07-11 15:46:54.0 +0200
@@ -38,10 +38,6 @@ Boston, MA 02110-1301, USA.  */
 #include "splay-tree.h"
 
 static void splay_tree_delete_helper (splay_tree, splay_tree_node);
-static inline void rotate_left (splay_tree_node *,
-   splay_tree_node, splay_tree_node);
-static inline void rotate_right (splay_tree_node *,
-   splay_tree_node, splay_tree_node);
 static void splay_tree_splay (splay_tree, splay_tree_key);
 static int splay_tree_foreach_helper (splay_tree, splay_tree_node,
   splay_tree_foreach_fn, void*);
@@ -106,95 +102,103 @@ splay_tree_delete_helper (splay_tree sp,
 #undef VDEL
 }
 
-/* Rotate the edge joining the left child N with its parent P.  PP is the
-   grandparents pointer to P.  */
+/* Splay SP around KEY.
+   This works alot like spliting a BST except if you traverse
+   left left or right right you first rotate the root before splitting
+   then move down a node.  */
 
-static inline void
-rotate_left (splay_tree_node *pp, splay_tree_node p, splay_tree_node n)
+static void
+splay_tree_splay (splay_tree sp, splay_tree_key key)
 {
-  splay_tree_node tmp;
-  tmp = n->right;
-  n->right = p;
-  p->left = tmp;
-  *pp = n;
-}
+  if (sp->root == 0)
+return;
 
-/* Rotate the edge joining the right child N with its parent P.  PP is the
-   grandparents pointer to P.  */
+  /* temp_tree.left is all the nodes less than key while
+ temp_tree.right is all the nodes greater than key */
+  struct splay_tree_node_s temp_tree;
+
+  /* these are the points we will add new nodes to the respective trees */
+  splay_tree_node left_ptr;
+  splay_tree_node right_ptr;
 
-static inline void
-rotate_right (splay_tree_node *pp, splay_tree_node p, splay_tree_node n)
-{
-  splay_tree_node tmp;
-  tmp = n->left;
-  n->left = p;
-  p->right = tmp;
-  *pp = n;
-}
+  /* current node we are splitting the tree at */
+  splay_tree_node current_node;
 
-/* Bottom up splay of key.  */
+  splay_tree_node tmp_node;
+  int comparison;
 
-static void
-splay_tree_splay (splay_tree sp, splay_tree_key key)
-{
-  if (sp->root == 0)
+  temp_tree.left = temp_tree.right = 0;
+  left_ptr = right_ptr = &temp_tree;
+
+  current_node = sp->root;
+  comparison = (*sp->comp) (key, current_node->key);
+
+  /* no splaying need */
+  if (comparison == 0)
 return;
 
-  do {
-int cmp1, cmp2;
-splay_tree_node n, c;
-
-n = sp->root;
-cmp1 = (*sp->comp) (key, n->key);
-
-/* Found.  */
-if (cmp1 == 0)
-  return;
-
-/* Left or right?  If no child, then we're done.  */
-if (cmp1 < 0)
-  c = n->left;
-else
-  c = n->right;
-if (!c)
-  return;
-
-/* Next one left or right?  If found or no child, we're done
-   after one rotation.  */
-cmp2 = (*sp->comp) (key, c->key);
-if (cmp2 == 0
-|| (cmp2 < 0 && !c->left)
-|| (cmp2 > 0 && !c->right))
-  {
-   if (cmp1 < 0)
- rotate_left (&sp->root, n, c);
-   else
- rotate_right (&sp->root, n, c);
-return;
-  }
-
-/* Now we have the four cases of double-rotation.  */
-if (cmp1 < 0 && cmp2 < 0)
-  {
-   rotate_left (&n->left, c, c->left);
-   rotate_left (&sp->root, n, n->left);
-  }
-else if (cmp1 > 0 && cm