This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: parallelized 'ld'?


> Automatically expanding hashtables when they reach ludicrous overload
> levels isn't that hard -- I've been doing it without a second thought
> in everything I've written for the last twenty years.  No?

Here's a quick patch to implement that, at least in a naive way.  See
if this makes a difference in link speed (at least for large apps; I
don't notice a significant speedup for linking cc1) and if it's worth
the effort I'll document it, clean it up, test it, and commit it.

Index: bfd/bfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in.h,v
retrieving revision 1.64
diff -p -2 -r1.64  bfd/bfd-in.h
*** bfd/bfd-in.h	11 Jul 2003 14:59:40 -0000	1.64
--- bfd/bfd-in.h	26 Aug 2003 17:58:40 -0000
*************** struct bfd_hash_table
*** 386,389 ****
--- 386,391 ----
    /* The number of slots in the hash table.  */
    unsigned int size;
+   /* The number of entries in the hash table.  */
+   unsigned int count;
    /* A function used to create new elements in the hash table.  The
       first entry is itself a pointer to an element.  When this
Index: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.233
diff -p -2 -r1.233  bfd/bfd-in2.h
*** bfd/bfd-in2.h	8 Aug 2003 10:14:50 -0000	1.233
--- bfd/bfd-in2.h	26 Aug 2003 17:58:40 -0000
*************** struct bfd_hash_table
*** 393,396 ****
--- 393,398 ----
    /* The number of slots in the hash table.  */
    unsigned int size;
+   /* The number of entries in the hash table.  */
+   unsigned int count;
    /* A function used to create new elements in the hash table.  The
       first entry is itself a pointer to an element.  When this
Index: bfd/hash.c
===================================================================
RCS file: /cvs/src/src/bfd/hash.c,v
retrieving revision 1.9
diff -p -2 -r1.9  bfd/hash.c
*** bfd/hash.c	30 Nov 2002 08:39:39 -0000	1.9
--- bfd/hash.c	26 Aug 2003 17:58:41 -0000
*************** SUBSUBSECTION
*** 296,300 ****
  
  /* The default number of entries to use when creating a hash table.  */
! #define DEFAULT_SIZE (4051)
  
  /* Create a new hash table, given a number of entries.  */
--- 296,365 ----
  
  /* The default number of entries to use when creating a hash table.  */
! #define DEFAULT_SIZE (4093)
! 
! /* The following function returns a nearest prime number which is
!    greater than N, and near a power of two.  Copied from libiberty.  */
! 
! static unsigned long
! higher_prime_number (n)
!      unsigned long n;
! {
!   /* These are primes that are near, but slightly smaller than, a
!      power of two.  */
!   static const unsigned long primes[] = {
!     (unsigned long) 7,
!     (unsigned long) 13,
!     (unsigned long) 31,
!     (unsigned long) 61,
!     (unsigned long) 127,
!     (unsigned long) 251,
!     (unsigned long) 509,
!     (unsigned long) 1021,
!     (unsigned long) 2039,
!     (unsigned long) 4093,
!     (unsigned long) 8191,
!     (unsigned long) 16381,
!     (unsigned long) 32749,
!     (unsigned long) 65521,
!     (unsigned long) 131071,
!     (unsigned long) 262139,
!     (unsigned long) 524287,
!     (unsigned long) 1048573,
!     (unsigned long) 2097143,
!     (unsigned long) 4194301,
!     (unsigned long) 8388593,
!     (unsigned long) 16777213,
!     (unsigned long) 33554393,
!     (unsigned long) 67108859,
!     (unsigned long) 134217689,
!     (unsigned long) 268435399,
!     (unsigned long) 536870909,
!     (unsigned long) 1073741789,
!     (unsigned long) 2147483647,
! 					/* 4294967291L */
!     ((unsigned long) 2147483647) + ((unsigned long) 2147483644),
!   };
! 
!   const unsigned long *low = &primes[0];
!   const unsigned long *high = &primes[sizeof(primes) / sizeof(primes[0])];
! 
!   while (low != high)
!     {
!       const unsigned long *mid = low + (high - low) / 2;
!       if (n >= *mid)
! 	low = mid + 1;
!       else
! 	high = mid;
!     }
! 
!   /* If we've run out of primes, abort.  */
!   if (n > *low)
!     {
!       fprintf (stderr, "Cannot find prime bigger than %lu\n", n);
!       abort ();
!     }
! 
!   return *low;
! }
  
  /* Create a new hash table, given a number of entries.  */
*************** bfd_hash_table_init_n (table, newfunc, s
*** 327,330 ****
--- 392,396 ----
    memset ((PTR) table->table, 0, alloc);
    table->size = size;
+   table->count = 0;
    table->newfunc = newfunc;
    return TRUE;
*************** bfd_hash_lookup (table, string, create, 
*** 397,400 ****
--- 463,467 ----
    if (hashp == (struct bfd_hash_entry *) NULL)
      return (struct bfd_hash_entry *) NULL;
+   table->count ++;
    if (copy)
      {
*************** bfd_hash_lookup (table, string, create, 
*** 415,418 ****
--- 482,514 ----
    hashp->next = table->table[index];
    table->table[index] = hashp;
+ 
+   if (table->count > table->size * 3 / 4)
+     {
+       int newsize = higher_prime_number (table->size);
+       struct bfd_hash_entry **newtable, *he;
+       unsigned int hi;
+       unsigned int alloc;
+ 
+       alloc = newsize * sizeof (struct bfd_hash_entry *);
+ 
+       fprintf(stderr, "dj: expand count %d size %d to %d\n", table->count, table->size, newsize);
+ 
+       newtable = ((struct bfd_hash_entry **)
+ 		  objalloc_alloc ((struct objalloc *) table->memory, alloc));
+       memset ((PTR) newtable, 0, alloc);
+ 
+       for (hi = 0; hi < table->size; hi ++)
+ 	while (table->table[hi])
+ 	  {
+ 	    int index;
+ 	    he = table->table[hi];
+ 	    table->table[hi] = he->next;
+ 	    index = he->hash % newsize;
+ 	    he->next = newtable[index];
+ 	    newtable[index] = he;
+ 	  }
+       table->table = newtable;
+       table->size = newsize;
+     }
  
    return hashp;
Index: libiberty/hashtab.c
===================================================================
RCS file: /cvs/src/src/libiberty/hashtab.c,v
retrieving revision 1.23
diff -p -2 -r1.23  libiberty/hashtab.c
*** libiberty/hashtab.c	19 Jun 2003 20:05:36 -0000	1.23
--- libiberty/hashtab.c	26 Aug 2003 17:58:41 -0000
*************** higher_prime_number (n)
*** 125,129 ****
      {
        const unsigned long *mid = low + (high - low) / 2;
!       if (n > *mid)
  	low = mid + 1;
        else
--- 125,129 ----
      {
        const unsigned long *mid = low + (high - low) / 2;
!       if (n >= *mid)
  	low = mid + 1;
        else


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]