HP3000-L Archives

November 1999, Week 5

HP3000-L@RAVEN.UTC.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Stan Sieler <[log in to unmask]>
Reply To:
Stan Sieler <[log in to unmask]>
Date:
Mon, 29 Nov 1999 11:47:19 -0800
Content-Type:
text/plain
Parts/Attachments:
text/plain (178 lines)
Re:
> Per Ostberg writes:
> >1) the running program needs to extensively check if there is a
> >breakpoint set
> >2) no optimization can be made by the compiler
>
> The actual reason is #2: when the compiler is asked to produce symbolic

Actually, there's far more overhead due to #1, if you rephrase it a bit.
The problem is that at every procedure entry, procedure exit, and
(possibly, depending upon compiler implementation) every statement,
there's a "conditional breakpoint" instruction emitted by the compiler (and,
unless something special is done at link time, is in the program binary code).

Let's just assume the common conditional breakpoints are emitted (procedure
entry and procedure exit).  That's going to add about 78 microseconds per
procedure call (on a 3000/968).

Yes, #2 is important as well...but it depends upon how many procedure
calls you make.  If you have big procedures that loop a lot within themselves,
#2 is more important than #1.  If you have a lot of procedures that do
a small amount each, #1 is more important.

> So it's impossible to do symbolic debugging on optimized code on the
> HP 3000, and difficult even on those few systems which support it.

It's surprisingly good on HP-UX as of 11.0 (or so) ... they put a lot
of effort into this area in that group that ignores the HP 3000 :(

> Even with symbolic debugging turned on, the running
> program never has to check for breakpoints; that's done
> (in effect) by the hardware. When you set a breakpoint in a program, the
> debugger replaces the first instruction of the statement on which you've
> set the breakpoint with an illegal instruction.

True...but, "symdebug 'toolset'$ emits breakpoints *into the code stream*.

BTW, you can tell the linker to convert those breakpoints into NOPs
by specifying "NODEBUG" on your LINK command.

They're called "conditional" breakpoints because they don't always
interrupt your program all the way back to the debugger.  If, however,
you run your program as:

   :run prog; debug
   trap t a
   c

then you'll pop up into the debugger at every procedure entry and exit!

Here's a sample program Pascal program to demonstrate the potential
overhead.  Timings follow it.

----------------cut here------------------
$symdebug 'toolset'$

program debug_test (output);

var
   old_plabel     : integer;

Function  proctime            : integer;     intrinsic;
Procedure terminate;                         intrinsic;
Function  timer               : integer;     intrinsic;
Procedure xcontrap;                          intrinsic;

{**************************************************************}
function  add1 (n : integer) : integer;

   begin

   add1 := n + 1;

   end {add1 proc};
{**************************************************************}
procedure cy_handler;

   begin

   terminate;

   end {cy_handler proc};
{**************************************************************}
procedure looper (n : integer);

   var
      loops       : integer;

   begin

   loops := 0;

   while loops < n do
      loops := add1 (loops);

   end {looper proc};
{**************************************************************}
procedure test (n : integer);

   var
      ct          : integer;
      et          : integer;
      rslt        : integer;

   begin

   et := timer;
   ct := proctime;

   looper (n);

   ct := proctime - ct;
   et := timer - et;
   if et < 0 then             {handle TIMER rollover}
      et := et + 2073600000;  {# of millisecs in 24 days}
      ;

   writeln ('looper (', n:8, ') took ',
                  ct:8, ' CPU, ',
                  et:8, ' elapsed millisecs');

   end {test proc};
{**************************************************************}

begin

xcontrap (baddress (cy_handler), old_plabel);

test (  1000);

test ( 10000);

test (100000);

end.


Here's the binary code, showing a couple of the conditional breakpoints:
   $3a ($6c) nmdebug > dc looper, 10
   000050fc  looper         6bc23fd9  STW      2,-20(0,30)
   00005100  looper+$4      37de0080  LDO      64(30),30
   00005104  looper+$8      6bda3f39  STW      26,-100(0,30)
   00005108  looper+$c      0001400e  BREAK    (proc enter)
   0000510c  looper+$10     6bc03f91  STW      0,-56(0,30)
   00005110  looper+$14     4bd33f91  LDW      -56(0,30),19
   00005114  looper+$18     4bd43f39  LDW      -100(0,30),20
   00005118  looper+$1c     8a934032  COMBF,<,N19,20,looper+$3c
   0000511c  looper+$20     e85f1e75  BL       add1,2
   00005120  looper+$24     4bda3f91  LDW      -56(0,30),26
   00005124  looper+$28     6bdc3f91  STW      28,-56(0,30)
   00005128  looper+$2c     4bd53f91  LDW      -56(0,30),21
   0000512c  looper+$30     4bd63f39  LDW      -100(0,30),22
   00005130  looper+$34     82d55fcd  COMBT,<  21,22,looper+$20
   00005134  looper+$38     08000240  OR       0,0,0
   00005138  looper+$3c     0001600e  BREAK    (proc exit)

Note the "BREAK (proc enter)" and "BREAK (proc exit)" ... those are the
procedure entry/exit breakpoints.

LINK ...; NODEBUG
RUN...

looper (    1000) took        0 CPU,        0 elapsed millisecs
looper (   10000) took        3 CPU,        3 elapsed millisecs
looper (  100000) took       35 CPU,       34 elapsed millisecs


LINK ...
RUN
looper (    1000) took       78 CPU,       79 elapsed millisecs
looper (   10000) took      780 CPU,      795 elapsed millisecs
looper (  100000) took     7875 CPU,     7916 elapsed millisecs



Stan Sieler                                           [log in to unmask]
www.allegro.com/sieler/wanted/index.html          www.allegro.com/sieler

ATOM RSS1 RSS2