public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* RFC remove cache thrashing
@ 2004-10-19  2:28 David Anderson
  2004-10-19 13:20 ` Daniel Jacobowitz
  0 siblings, 1 reply; 2+ messages in thread
From: David Anderson @ 2004-10-19  2:28 UTC (permalink / raw)
  To: gdb

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 3919 bytes --]

gdb has N-squared behavior on getting registers when nptl
threads on Linux are in use.  gdb thrashes the register-cache.

This is noticeably slow when the register count is large (over 300),
such as Itanium:  doing an interactive function call can
take several seconds.

Performance can be improved with more uses of CANNOT_FETCH_REGISTER
and CANNOT_STORE_REGISTER because of the existence of large numbers
of raw-register numbers that are not treated as raw.
  Changing
  regcache.c:  if (CANNOT_STORE_REGISTER (regnum))
  to
  regcache.c:  if (!regcache->readonly_p && !CANNOT_FETCH_REGISTER(regnum))
  regcache.c:  if (CANNOT_STORE_REGISTER (regnum)) {
  thread-db.c:  if(regno != -1 && CANNOT_FETCH_REGISTER(regno)) {
  thread-db.c:  if(regno != -1 && CANNOT_STORE_REGISTER(regno)) {

But that's a minor improvement as the time-delay is still
noticeable.

Here is a stack trace with a tiny bit of commentary
(involving an interactive-function-call).

The following shows gdb thrashing it's register cache.
#0  registers_changed () at ../../src/gdb/regcache.c:530
#1  0x40000000001df9e0 in regcache_raw_supply (regcache=0x600000000012cea0,
    regnum=0, buf=0x0) at ../../src/gdb/regcache.c:1113
#2  0x40000000000cac50 in fetch_register (regnum=0)
    at ../../src/gdb/infptrace.c:289
#3  0x40000000000cb1d0 in fetch_inferior_registers (regnum=0)
    at ../../src/gdb/infptrace.c:327
#4  0x40000000000e5d20 in thread_db_fetch_registers (regno=-1)
    at ../../src/gdb/thread-db.c:1059
#5  0x40000000000dfaa0 in ps_lgetregs (ph=0x6000000000044a44, lwpid=31919,
	ps_lgetregs changes the value of inferior_ptid on entry
	{to perhaps 1277,1277,0} using the BUILD_LWP macro
        and requests all registers from the inferior.

        On return inferior_ptid of {1277,0, 25643240009} is
        restored.
	Which means that the register-cache gets thrashed.

    gregset=0x60000fffffff64a0) at ../../src/gdb/proc-service.c:235
#6  0x20000000025a4140 in td_thr_getgregs (th=0x60000000003f11a8,
    regset=0x60000fffffff64a0) at td_thr_getgregs.c:26
#7  0x40000000000e5e10 in thread_db_fetch_registers (regno=-1)
    at ../../src/gdb/thread-db.c:1066
#8  0x40000000000e65d0 in thread_db_store_registers (regno=351)
	Requests all registers.
	inferior ptid might be {1277,0, 25643240009}
    at ../../src/gdb/thread-db.c:1116
#9  0x40000000001dd590 in regcache_raw_write (regcache=0x600000000012cea0,
    regnum=351, buf=0x60000fffffff7d40) at ../../src/gdb/regcache.c:855
#10 0x40000000001dda60 in regcache_cooked_write (regcache=0x600000000012cea0,
    regnum=351, buf=0x60000fffffff7d40) at ../../src/gdb/regcache.c:874
#11 0x40000000001dd880 in deprecated_write_register_gen (regnum=351,
    buf=0x60000fffffff7d40 "\bÃÿ\177ÿ\017") at ../../src/gdb/regcache.c:865
#12 0x40000000001df4c0 in write_register (regnum=351, val=6917546617679627016)
    at ../../src/gdb/regcache.c:1073
#13 0x40000000000b51b0 in ia64_push_dummy_call (gdbarch=0x600000000012be10,
    function=0x6000000000467490, regcache=0x600000000012cea0,
    bp_addr=4611686018427389088, nargs=2, args=0x60000fffffff8048,
    sp=6917546619827102608, struct_return=0, struct_addr=0)
    at ../../src/gdb/ia64-tdep.c:3094
#14 0x40000000002d9150 in gdbarch_push_dummy_call (


One way to avoid thrashing the cache
is to creat multiple register caches. 

Has this multiple-register-cache idea been considered seriously before?
Is there any proposed outline-of-change?

One alternative:
 registers_changed(), if altered to mean 'get rid of all
 existing caches' would then be safe and existing callers
 would be safe.   ps_lgetregs (proc-service.c) could be changed to 
 request a cache-switch (actually twice) so no
 more trashing.  Minimally invasive and precise.

Does this seem like a worthwhile change (abstractly I mean)?

Are other designs better (such as...?)?

Comments? Flames?
David B. Anderson davea at sgi dot com http://reality.sgiweb.org/davea

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: RFC remove cache thrashing
  2004-10-19  2:28 RFC remove cache thrashing David Anderson
@ 2004-10-19 13:20 ` Daniel Jacobowitz
  0 siblings, 0 replies; 2+ messages in thread
From: Daniel Jacobowitz @ 2004-10-19 13:20 UTC (permalink / raw)
  To: David Anderson; +Cc: gdb

On Mon, Oct 18, 2004 at 04:39:44PM -0700, David Anderson wrote:
> gdb has N-squared behavior on getting registers when nptl
> threads on Linux are in use.  gdb thrashes the register-cache.

I hadn't replied to your past posts because I didn't have time to
reproduce the problem; last time I checked, it wasn't quadratic.  I
don't know what about your setup made the difference, or maybe my
measurements are just out of date.

Fixing this is very easy.  I plan to remove the entire mess of affected
code, once I finish renaming thread-db.c, which will hopefully be this
week.  We don't need to use thread-db for registers at all.

> Has this multiple-register-cache idea been considered seriously before?
> Is there any proposed outline-of-change?

We need to get rid of all the remaining references to the "current"
registers first.  I don't think we're quite there yet.

-- 
Daniel Jacobowitz

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-10-18 23:47 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-19  2:28 RFC remove cache thrashing David Anderson
2004-10-19 13:20 ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).