Board index » delphi » Speeding things up with Inline-Assembly

Speeding things up with Inline-Assembly

Quote
Thingy wrote:

> Hi !

> I've written a graphics library for pascal that uses almost 95%
> assembly code. Would converting the routines from
> Procedure Name;Assembler;
> ASM END;
> into an inline-procedure faster ?

Ok, here I go, trying to explain things I dunno anything about :)
Inline was the only was of using asm in a Pascal program before ver 6.
You had to "assemble" the asm code youselfe. Ok, so in tp/bp 6 they
included support for "real" asm code. So, the only diffrence is that
it's a real pain in the *** to write inline code (or so it seems :),
compared to asm code. And, no, it's not faster.

Quote
> What exactly is the difference in the resulting code and how can
> I write inline-code w/o having to look up the opcodes of my asm-code ?
> Does anyone have a good tutor on writing inline-code for BP ?

> Thank you,

> Kay

> PS: I am looking for a graphician who is interested in helping me
> writing a few small shareware/PD-games... I don't need professional
> looking sprites or tiles - they just have to be better than mine - and
> I am not an artist at all ;-)

Please correct me if I'm wrong :)

- Asbj?rn

 

Re:Speeding things up with Inline-Assembly


Quote
Thingy wrote:
> Hi !

> I've written a graphics library for pascal that uses almost 95%
> assembly code. Would converting the routines from
> Procedure Name;Assembler;
> ASM END;
> into an inline-procedure faster ?

> What exactly is the difference in the resulting code and how can
> I write inline-code w/o having to look up the opcodes of my asm-code ?

There's a marginal speed difference, because inline data is inserted
directly into the code, rather than called; the overhead is lost because
there's no need to push CS:IP, jump the the call address, and set up the
stack frame to call, then release the stack fram and pop CS:IP.  BUT
(and this is a major BUT), every time you call that procedure the code
inserted into the code (hence the name "inline").  The result of this is
that if you convert a 230-byte BASM procedure to inline, and then your
code has twenty calls to the inline procedure, this will add 4600 bytes
of code to the final compilation, not 230 plus 5(?) bytes for each call.

Also, since inline functions and procedures are macro-like, you can't
use @, seg, ofs, or addr with them because the particular function
doesn't actually have an address that can be referred to.

The BP7 Language Guide recommends as a rule of thumb that inline not be
used for any function or procedure over 10 bytes, which is probably not
a bad idea -- ironically, though, on the previous page, they have a
sample procedure which looks to be about 15 bytes.

Even in TP7, inline has its places, but replacing assembler procedures
is NOT one of them.

Quote
> Does anyone have a good tutor on writing inline-code for BP ?

I don't know of one, but a good, practical way to get started is to use
DEBUG.EXE and learn to use the "a" (assemble) and "u" (unassemble)
commands.  These are in the manuals and in the DOS online help (for
versions 6.x).

Quote
> Thank you,

> Kay

> PS: I am looking for a graphician who is interested in helping me
> writing a few small shareware/PD-games... I don't need professional
> looking sprites or tiles - they just have to be better than mine - and
> I am not an artist at all ;-)

Heh, I have a quick graphic library I'm working on, but I'm not much
good at graphic design.  Well, I like to doodle now and then, and if
there's something I could help out with, let me know.  :-)

--
Scott Earnest        | We now return you to our regularly |
set...@ix.netcom.com | scheduled chaos and mayhem. . . .  |

Re:Speeding things up with Inline-Assembly


Quote
Asbj=F8rn wrote:
> [...]
> Please correct me if I'm wrong :)

Rather than repeat myself, see my follow-up directly to "Thingy"
detailing the differences.  (I.e., consider yourself corrected.  ;-)

Quote
> - Asbj=F8rn

-- =

Scott Earnest        | We now return you to our regularly |
set...@ix.netcom.com | scheduled chaos and mayhem. . . .  |

Re:Speeding things up with Inline-Assembly


Quote
Scott Earnest wrote:

> Asbj?rn wrote:

> > [...]
> > Please correct me if I'm wrong :)

> Rather than repeat myself, see my follow-up directly to "Thingy"
> detailing the differences.  (I.e., consider yourself corrected.  ;-)

Is there a diffrence between

procedure Int10A; assembler;
asm
   int 10h
end;

and

procedure Int10I; inline ($CD, $10);

or however you use the inline code?

- Asbj?rn

Re:Speeding things up with Inline-Assembly


Quote
Asbj=F8rn wrote:
> Scott Earnest wrote:

> > Asbj=F8rn wrote:

> > > [...]
> > > Please correct me if I'm wrong :)

> > Rather than repeat myself, see my follow-up directly to "Thingy"
> > detailing the differences.  (I.e., consider yourself corrected.  ;-)
> =
> Is there a diffrence between
> =
> procedure Int10A; assembler;
> asm
>    int 10h
> end;
> =
> and
> =
> procedure Int10I; inline ($CD, $10);
> =
> or however you use the inline code?

Yes, there is.  If you were to place calls to each in a short program
and look at what they looked like together in a de{*word*81}, the difference
is noticeable quickly.  I used this short program (mainly a compacted
version of yours above):

program intdebug;

procedure Int10A; assembler; asm int 10h; end;

procedure Int10I; inline ($cd/$10);

begin
  Int10A;
  Int10I;
end.

A disassembly showed:

INTDEBUG.8:  Int10A;
  cs:0012 0E             push   cs
  cs:0013 E8EAFF         call   INTDEBUG.INT10A
INTDEBUG.9:  Int10I;
  cs:0016 CD10           int    10

The first is an indirect call, the second is an immediate image of the
inline data.  For something so short, the inline is more optimal than
the assembler function, but as an assembler function grows, the
assembler function quickly becomes more size-efficient than the inline
code, which is just duplicated.

The procedure call here is actually relatively fast, since it's a near
relative call, but far calls take longer, and in protected mode the
calling time for a far call for a simple procedure like that might be
several times the amount of time required to execute the actual code
body!

Quote
> - Asbj=F8rn

-- =

Scott Earnest        | We now return you to our regularly |
set...@ix.netcom.com | scheduled chaos and mayhem. . . .  |

Re:Speeding things up with Inline-Assembly


Quote
Thingy wrote:
> On Thu, 20 Feb 1997 01:59:16 -0800, Scott Earnest
> <set...@ix.netcom.com> wrote:
> [snip]

> Hi :-)

> This tells me that I was right about the directly inserted code....
> mmm, this brings up the old question of optimizing speed versus size.
> Since it doesn't use any overhead - we would gain a speed AND
> size gain in small procedures that are only called maybe once or
> twice, like a small Set13H ?

> Procedure Set13h;Assembler;
> ASM
>  mov ax,13h
>  int 10h
> END;

> Since this procedure is only called once I could implement it
> directly into the other code via

> WriteLN('Hello World');
> ASM
>  mov ax,13h
>  int 10h
> END;
> ...other pascal code

You can do this, and yes, it has no calling overhead, but that's not
inline code as I was referring to.  By inline, I was referring to
directly inserted code using the "inline" directive.  What you show is
BASM code placed inline in code, which isn't *quite* the same thing.
The inline version of above would be:

procedure Set13h; inline (
  $b8/>$13/   {mov   ax,0013h}
  $cd/$10     {int   10h}
);

Quote
> This would (should) actually be faster and smaller....?
> Is there a different method of implementing assembler code into pascal
> source code ?

Yes, but trying to optimize that is a waste of time, because it's not at
all critical.  Good optimization involves t{*word*220} non-trivial parts of
code.  For all it matters, you wouldn't have any significant speed gain
over:

procedure Set13h;

var
  r : registers;

begin
  r.ax := $13;
  intr ($10,r);
end;

Your only advantage of using the assembler code is that it optimally
smaller.  Unless you do something weird, like call this procedure 10000
times, which one you use really won't affect the over-all run time of
the program.

Quote
> What actually bothers me is the missing 386code-support, but I think
> there are lots of ppl who want Borland to continue developing
> BorlandPascal.

It's a 286-level compiler.  For 32-bit BASM, you can either use Borland
Delphi, or try out TMT Pascal.

Quote
> >> Does anyone have a good tutor on writing inline-code for BP ?

> >I don't know of one, but a good, practical way to get started is to use
> >DEBUG.EXE and learn to use the "a" (assemble) and "u" (unassemble)
> >commands.  These are in the manuals and in the DOS online help (for
> >versions 6.x).

> UGH! :-)
> I usually go to TurboDe{*word*81} for such things - which is
> (unfortunately) a must for when I try to use 32bit commands.
> It's just not the best way.....

True, I recently used it to double-check some erroneous code DEBUG was
producing for 32-bit code (pushing and popping FS/GS), and it is far
more robust than DEBUG, but, AFAIK, TD doesn't have a mini assembler
built in that lets you key in code -- you'd have to compile snippets in
ASM to a small .COM file, then load that.

Quote
> >Scott Earnest        | We now return you to our regularly |
> >set...@ix.netcom.com | scheduled chaos and mayhem. . . .  |

> Kay

--
Scott Earnest        | We now return you to our regularly |
set...@ix.netcom.com | scheduled chaos and mayhem. . . .  |

Re:Speeding things up with Inline-Assembly


Quote
Scott Earnest wrote:
> [snip!]
> True, I recently used it to double-check some erroneous code DEBUG was
> producing for 32-bit code (pushing and popping FS/GS), and it is far
> more robust than DEBUG, but, AFAIK, TD doesn't have a mini assembler
> built in that lets you key in code -- you'd have to compile snippets in
> ASM to a small .COM file, then load that.

Hmmm, disregard that last bit.  I happened to find the command that does
this.  (Hitting space in the CPU window calls up a dialog that lets you
enter something to assemble -- how novel! :-)

Quote
> > >Scott Earnest        | We now return you to our regularly |
> > >set...@ix.netcom.com | scheduled chaos and mayhem. . . .  |

> > Kay

> --
> Scott Earnest        | We now return you to our regularly |
> set...@ix.netcom.com | scheduled chaos and mayhem. . . .  |

--
Scott Earnest        | We now return you to our regularly |
set...@ix.netcom.com | scheduled chaos and mayhem. . . .  |

Re:Speeding things up with Inline-Assembly


Quote
On Thu, 20 Feb 1997 17:57:50 -0800,  Asbj?rn <bh...@sn.no> wrote:
>Is there a diffrence between

>procedure Int10A; assembler;
>asm
>   int 10h
>end;

>and

>procedure Int10I; inline ($CD, $10);

>or however you use the inline code?

>- Asbj?rn

Here we go again, with characters best left unused.  Have you any idea of the
difficulty of discerning the difference between Int1O1, Int10I, and Int10l?  Now
consider Int1o1, Int10i, Int10L.  Please, restrict the letters i and o to
lowercase and the letter L to uppercase.

I'll also assume you meant Procedure Int10i; inline($CD /$10);

Yes.  This is what Scott has been trying to explain.  Int10a exists as a
procedure. Since it uses the "assembler" keyword and has no parameters or local
variables, it will not contain the usual preamble for establishing a stack
frame. However, it will contain a ret instruction (retn or retf depending upon
whether the procedure is near or far).

Int10i exists only in the compiler's symbol table.  When you invoke Int10a, the
compiler generates a call instruction.  When you invoke Int10i the compiler
embeds $CD $10 at the current code position, hence the name *inline*.  This
would be like you entering "ASM int $10 END" rather than Int10i.

Once more, when you invoke Int10a, your program will execute
"CALL Int10a; Int $10; RET".  When you invoke Int10i, your program will execute
"Int $10"

Hope this helps.

    ...red

Re:Speeding things up with Inline-Assembly


[damn lost first line]

Quote
>directly into the code, rather than called; the overhead is lost because
>there's no need to push CS:IP, jump the the call address, and set up the
>stack frame to call, then release the stack fram and pop CS:IP.  BUT
>(and this is a major BUT), every time you call that procedure the code
>inserted into the code (hence the name "inline").  The result of this is
>that if you convert a 230-byte BASM procedure to inline, and then your
>code has twenty calls to the inline procedure, this will add 4600 bytes
>of code to the final compilation, not 230 plus 5(?) bytes for each call.

According to my knowledge, INLINE funcs/procs are only inserted in the
code wherever called if they are defined like this:

procedure FragMe;
Inline($CD/$1C);

If you define it like THIS:

procedure FragMe;
begin
  Inline($CD/$1C);
end;

then you won't have that problem. It will be inserted exactly as normal
procedures are. The up-side of using a begin/end statement with it is
that you can do your own analysis of it inside. i.e. insert inline code
to move AX into a variable, and do what you want based on it in PASCAL..

But its still best (not to mention freaking easiest) to use assembly....
Inline sucks. Nobody can read it! :) (well, I guess thats good if you
don't want people easily ripping your source..;)
--
    Valdus -/- Hilton Janfield -(- sysop of dark genesis bbs -\- Valdus
dark genesis bbs system * 250/561-2850 * 14400 baud * lots of games * MORE!
** Official Distribution Site for OutWorld Arts, Outlaw Triad, and SWAG! **

Re:Speeding things up with Inline-Assembly


Quote
>Here we go again, with characters best left unused.  Have you any idea of the
>difficulty of discerning the difference between Int1O1, Int10I, and Int10l?  Now
>consider Int1o1, Int10i, Int10L.  Please, restrict the letters i and o to
>lowercase and the letter L to uppercase.

What is your {*word*30}ing problem man?

Any idiot can see the difference between 1 l I and O 0. Oh wait you
fagots are using winblows and os/2 AHAHAHAHAHAHAHHAHAHAHAHAHAHAHHA!!!!!!!

GET A REAL OPERATING SYSTEM!
--
    Valdus -/- Hilton Janfield -(- sysop of dark genesis bbs -\- Valdus
dark genesis bbs system * 250/561-2850 * 14400 baud * lots of games * MORE!
** Official Distribution Site for OutWorld Arts, Outlaw Triad, and SWAG! **

Re:Speeding things up with Inline-Assembly


Quote
>Is there a diffrence between
>procedure Int10A; assembler;
>asm
>   int 10h
>end;
>procedure Int10I; inline ($CD, $10);

>or however you use the inline code?

Yes. Int10I would be inserted into the code wherever its called, instead
of just once with pointers to it like Int10A. See a pervious message of
mine for better references :)
--
    Valdus -/- Hilton Janfield -(- sysop of dark genesis bbs -\- Valdus
dark genesis bbs system * 250/561-2850 * 14400 baud * lots of games * MORE!
** Official Distribution Site for OutWorld Arts, Outlaw Triad, and SWAG! **

Re:Speeding things up with Inline-Assembly


Quote
Hilton Janfield wrote:
> What is your f***ing problem man?

> Any idiot can see the difference between 1 l I and O 0. Oh wait you
> ****** are using winblows and os/2 AHAHAHAHAHAHAHHAHAHAHAHAHAHAHHA!!!!!!!

> GET A REAL OPERATING SYSTEM!

Way to make friends in the newsgroup!

AME

Re:Speeding things up with Inline-Assembly


Quote
Roger E. Donais wrote:
>>Here we go again, with characters best left unused.  Have you any idea of the
>>difficulty of discerning the difference between Int1O1, Int10I, and Int10l?  Now
>>consider Int1o1, Int10i, Int10L.  Please, restrict the letters i and o to
>>lowercase and the letter L to uppercase.

Hilton Janfield responded:

Quote
>What is your {*word*30}ing problem man?

>Any idiot can see the difference between 1 l I and O 0. Oh wait you
>fagots are using winblows and os/2 AHAHAHAHAHAHAHHAHAHAHAHAHAHAHHA!!!!!!!

>GET A REAL OPERATING SYSTEM!

I'm sorry to disappoint you Hilton, but the difficulty is failing eyesight.  Of
course you wouldn't know or care about such things.

I find no humor in having to use a magnifying glass to tell the difference
between the numbers 0 and 8, or number 8 and letter B.  Other characters that
you take for granted that cause problems are periods and commas, semi-colons and
colons, just to name a few.

It never ceases to amaze me how some individuals seem to associate a handicap
with lack of intelligence.  FWIW Hilton, I and others like me are not idiots, we
just don't have your perfect vision...

    ...red

Re:Speeding things up with Inline-Assembly


In article: <330DA2E2....@ix.netcom.com>  Scott Earnest <set...@ix.netcom.com>
writes:

Quote

>The procedure call here is actually relatively fast, since it's a near
>relative call, but far calls take longer, and in protected mode the
>calling time for a far call for a simple procedure like that might be
>several times the amount of time required to execute the actual code
>body!

A far call on a 486 takes 18 cycles in real mode and 20 cycles in protected mode
according to my TASM reference manual. They do take twice as long as a RM far
call on 286's and 386's (~26+m and ~34+m respectively). Anyone know what the
score is on a Pentium?

-- Jay

 --------------------------------------------------------------------------
| Jason Burgon - author of Graphic Vision, TV-Like GUI for 256 Colour SVGA |
| g...@jayman.demon.co.uk   ftp://SimTel/msdos/turbopas/gv4svga1.zip         |
| ***NEW VERSION OF GV AVAILABLE FROM*** -> http://www.jayman.demon.co.uk  |
 --------------------------------------------------------------------------

Re:Speeding things up with Inline-Assembly


Quote
>> Any idiot can see the difference between 1 l I and O 0. Oh wait you
>> ****** are using winblows and os/2 AHAHAHAHAHAHAHHAHAHAHAHAHAHAHHA!!!!!!!
>> GET A REAL OPERATING SYSTEM!
>Way to make friends in the newsgroup!

Hehehe....Well, Microshit software has always sucked. The only decent
thing they've made is MS-DOS 6.2(2) and Internet Explorer (which could
have just as easily be written for DOS. Believe me. If/When I finish my
HTML parser I'll have it)
--
    Valdus -/- Hilton Janfield -(- sysop of dark genesis bbs -\- Valdus
dark genesis bbs system * 250/561-2850 * 14400 baud * lots of games * MORE!
** Official Distribution Site for OutWorld Arts, Outlaw Triad, and SWAG! **
Go to page: [1] [2]

Other Threads