This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
RFA: speed up SH simulator startup
- From: Joern RENNECKE <joern dot rennecke at st dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Tue, 13 Sep 2005 19:13:48 +0100
- Subject: RFA: speed up SH simulator startup
I used to be the SH simulator maintainer, but somehow I never made it
into the MAINTAINERS file,
so it apears I have to ask for a code review...
We are seeing more and more large testcases in the gcc/g++/libstdc++-v3 testsuite. E.g. ext/rope/3.cc wants to build a 50 MB string. But still, the majority
of testcases is very small. At the moment, memory is allocated with malloc,
and then cleared with memset (common/sim-memopt has a mmap option, but it
wouldn't help: it requires a large file to start with, and does a separate
clearing step too).
If we allocate too little memory, many tests will fail. If we allocate
too much, a lot of memory has to be cleared for every test, and the tests
won't finish in a day.
For a simple benchmark, I've run gcc.c-torture/execute/builtins/20010124-1.c
with sh-elf-run on i686-pc-linux-gnu X sh-elf (1.4 GHz Athlon MP).
Averages of ten runs (after two initial warm-up runs) are:
with -m21 (2 MB):
real 0m0.0296s
user 0m0.001s
sys 0m0.011s
with -m28 (256 MB):
real 0m1.400s
user 0m0.557s
sys 0m0.496s
A better way to allocate the memory is to mmap it anonymously, so that it
only gets actually allocated and zeroed on demand.
With the attached patch, the test executes much quicker, and independently
of the -m setting:
with -m21 (2 MB):
real 0m0.004s
user 0m0.001s
sys 0m0.001s
with -m28 (256 MB):
real 0m0.0041s
user 0m0.001s
sys 0m0.004s
Check-sim results are unchanged.
2005-09-13 J"orn Rennecke <joern.rennecke@st.com>
* interp.c (<sys/mman.h>): Include.
(mcalloc): New function / macro.
(mfree): New macro.
(sim_size): Use mcalloc and mfree.
Index: interp.c
===================================================================
RCS file: /cvs/src/src/sim/sh/interp.c,v
retrieving revision 1.17
diff -p -r1.17 interp.c
*** interp.c 2 Aug 2005 16:17:59 -0000 1.17
--- interp.c 13 Sep 2005 18:06:21 -0000
***************
*** 24,29 ****
--- 24,38 ----
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+ #ifdef HAVE_MMAP
+ #include <sys/mman.h>
+ # ifndef MAP_FAILED
+ # define MAP_FAILED -1
+ # endif
+ # if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
+ # define MAP_ANONYMOUS MAP_ANON
+ # endif
+ #endif
#include "sysdep.h"
#include "bfd.h"
*************** static void ppi_insn ();
*** 1715,1720 ****
--- 1724,1750 ----
#include "ppi.c"
+ /* Provide calloc / free versions that use an anonymous mmap. This can
+ significantly cut the start-up time when a large simulator memory is
+ required, because pages are only zeroed on demand. */
+ #ifdef MAP_ANONYMOUS
+ void *
+ mcalloc (size_t nmemb, size_t size)
+ {
+ void *page;
+
+ if (nmemb != 1)
+ size *= nmemb;
+ return mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
+ -1, 0);
+ }
+
+ #define mfree(start,length) munmap ((start), (length))
+ #else
+ #define mcalloc calloc
+ #define mfree(start,length) free(start)
+ #endif
+
/* Set the memory size to the power of two provided. */
void
*************** sim_size (power)
*** 1722,1738 ****
int power;
{
- saved_state.asregs.msize = 1 << power;
-
sim_memory_size = power;
if (saved_state.asregs.memory)
{
! free (saved_state.asregs.memory);
}
saved_state.asregs.memory =
! (unsigned char *) calloc (64, saved_state.asregs.msize / 64);
if (!saved_state.asregs.memory)
{
--- 1752,1768 ----
int power;
{
sim_memory_size = power;
if (saved_state.asregs.memory)
{
! mfree (saved_state.asregs.memory, saved_state.asregs.msize);
}
+ saved_state.asregs.msize = 1 << power;
+
saved_state.asregs.memory =
! (unsigned char *) mcalloc (1, saved_state.asregs.msize);
if (!saved_state.asregs.memory)
{
*************** sim_size (power)
*** 1741,1747 ****
saved_state.asregs.msize);
saved_state.asregs.msize = 1;
! saved_state.asregs.memory = (unsigned char *) calloc (1, 1);
}
}
--- 1771,1777 ----
saved_state.asregs.msize);
saved_state.asregs.msize = 1;
! saved_state.asregs.memory = (unsigned char *) mcalloc (1, 1);
}
}