This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
RE: changing the default hash table size (was improving ld performance)
- From: Andy Chittenden <achittenden at bluearc dot com>
- To: 'Nick Clifton' <nickc at redhat dot com>
- Cc: "'binutils at sources dot redhat dot com'" <binutils at sources dot redhat dot com>
- Date: Thu, 11 Mar 2004 09:37:17 -0000
- Subject: RE: changing the default hash table size (was improving ld performance)
Hi Nick
> There are no such options at present, but I think that this would be a
> very good idea. Would you like to develop a patch to do it ?
How's this:
Index: bfd/bfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in.h,v
retrieving revision 1.72
diff -c -w -r1.72 bfd-in.h
*** bfd/bfd-in.h 16 Feb 2004 18:46:40 -0000 1.72
--- bfd/bfd-in.h 11 Mar 2004 09:29:22 -0000
***************
*** 440,445 ****
--- 440,450 ----
bfd_boolean (*) (struct bfd_hash_entry *, void *),
void *info);
+ /* Allows the default size of a hash table to be configured. New hash
+ tables allocated using bfd_hash_table_init will be created with
+ this size. */
+ extern void bfd_hash_set_default_size (bfd_size_type);
+
#define COFF_SWAP_TABLE (void *) &bfd_coff_std_swap_table
/* User program access to BFD facilities. */
Index: bfd/hash.c
===================================================================
RCS file: /cvs/src/src/bfd/hash.c,v
retrieving revision 1.11
diff -c -w -r1.11 hash.c
*** bfd/hash.c 1 Dec 2003 06:33:01 -0000 1.11
--- bfd/hash.c 11 Mar 2004 09:29:22 -0000
***************
*** 53,58 ****
--- 53,59 ----
@* Looking Up or Entering a String::
@* Traversing a Hash Table::
@* Deriving a New Hash Table Type::
+ @* Changing the default Hash Table Size::
@end menu
INODE
***************
*** 87,92 ****
--- 88,97 ----
been allocated for a hash table. This will not free up the
<<struct bfd_hash_table>> itself, which you must provide.
+ @findex bfd_hash_set_default_size
+ Use <<bfd_hash_set_default_size>> to set the default size of
+ hash table to use.
+
INODE
Looking Up or Entering a String, Traversing a Hash Table, Creating and
Freeing a Hash Table, Hash Tables
SUBSECTION
***************
*** 296,301 ****
--- 301,307 ----
/* The default number of entries to use when creating a hash table. */
#define DEFAULT_SIZE (4051)
+ static size_t bfd_default_hash_table_size = DEFAULT_SIZE;
/* Create a new hash table, given a number of entries. */
***************
*** 339,345 ****
struct bfd_hash_table *,
const char *));
{
! return bfd_hash_table_init_n (table, newfunc, DEFAULT_SIZE);
}
/* Free a hash table. */
--- 345,351 ----
struct bfd_hash_table *,
const char *));
{
! return bfd_hash_table_init_n (table, newfunc,
bfd_default_hash_table_size);
}
/* Free a hash table. */
***************
*** 494,499 ****
--- 500,529 ----
}
}
}
+
+ /* extend this prime list if you want more granularity of hash table size.
*/
+ static bfd_size_type hash_size_primes[] = {
+ 4051, 8599, 16699
+ };
+ static const unsigned nhash_size_primes = sizeof(hash_size_primes) /
sizeof(hash_size_primes[0]);
+
+ void
+ bfd_hash_set_default_size(bfd_size_type hash_size) {
+ bfd_size_type new_hash_size = hash_size_primes[nhash_size_primes - 1];
+ int index;
+ /* work out best prime number near the hash_size */
+ for (index = 0; index < nhash_size_primes; ++index)
+ {
+ if (hash_size <= hash_size_primes[index])
+ {
+ new_hash_size = hash_size_primes[index];
+ break;
+ }
+ }
+ bfd_default_hash_table_size = new_hash_size;
+ fprintf(stderr, "setting hash size to %d - real size %d\n", hash_size,
new_hash_size);
+ }
+
/* A few different object file formats (a.out, COFF, ELF) use a string
table. These functions support adding strings to a string table,
Index: ld/ld.h
===================================================================
RCS file: /cvs/src/src/ld/ld.h,v
retrieving revision 1.21
diff -c -w -r1.21 ld.h
*** ld/ld.h 28 Jun 2003 05:28:54 -0000 1.21
--- ld/ld.h 11 Mar 2004 09:29:23 -0000
***************
*** 216,221 ****
--- 216,223 ----
/* If set, only search library directories explicitly selected
on the command line. */
bfd_boolean only_cmd_line_lib_dirs;
+
+ bfd_size_type hash_table_size;
} ld_config_type;
extern ld_config_type config;
Index: ld/ldmain.c
===================================================================
RCS file: /cvs/src/src/ld/ldmain.c,v
retrieving revision 1.78
diff -c -w -r1.78 ldmain.c
*** ld/ldmain.c 15 Feb 2004 02:24:53 -0000 1.78
--- ld/ldmain.c 11 Mar 2004 09:29:24 -0000
***************
*** 263,268 ****
--- 263,269 ----
config.has_shared = FALSE;
config.split_by_reloc = (unsigned) -1;
config.split_by_file = (bfd_size_type) -1;
+ config.hash_table_size = 0;
command_line.force_common_definition = FALSE;
command_line.inhibit_common_definition = FALSE;
command_line.interpreter = NULL;
***************
*** 337,342 ****
--- 338,346 ----
ldemul_before_parse ();
lang_has_input_file = FALSE;
parse_args (argc, argv);
+
+ if (config.hash_table_size != 0)
+ bfd_hash_set_default_size(config.hash_table_size);
ldemul_set_symbols ();
Index: ld/lexsup.c
===================================================================
RCS file: /cvs/src/src/ld/lexsup.c,v
retrieving revision 1.70
diff -c -w -r1.70 lexsup.c
*** ld/lexsup.c 7 Dec 2003 00:08:41 -0000 1.70
--- ld/lexsup.c 11 Mar 2004 09:29:24 -0000
***************
*** 116,121 ****
--- 116,122 ----
OPTION_FORCE_EXE_SUFFIX,
OPTION_GC_SECTIONS,
OPTION_NO_GC_SECTIONS,
+ OPTION_HASH_SIZE,
OPTION_CHECK_SECTIONS,
OPTION_NO_CHECK_SECTIONS,
OPTION_NO_UNDEFINED,
***************
*** 325,330 ****
--- 326,333 ----
{ {"no-gc-sections", no_argument, NULL, OPTION_NO_GC_SECTIONS},
'\0', NULL, N_("Don't remove unused sections (default)"),
TWO_DASHES },
+ { {"hash-size", required_argument, NULL, OPTION_HASH_SIZE},
+ '\0', NULL, N_("Set default hash table size"), TWO_DASHES },
{ {"help", no_argument, NULL, OPTION_HELP},
'\0', NULL, N_("Print option help"), TWO_DASHES },
{ {"init", required_argument, NULL, OPTION_INIT},
***************
*** 1205,1210 ****
--- 1208,1216 ----
case OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH:
command_line.accept_unknown_input_arch = FALSE;
break;
+ case OPTION_HASH_SIZE:
+ config.hash_table_size = strtoul (optarg, NULL, 0);
+ break;
case '(':
if (ingroup)
einfo (_("%P%F: may not nest groups (--help for usage)\n"));
--
Andy, BlueArc Engineering