English Amiga Board

English Amiga Board (http://eab.abime.net/index.php)
-   Coders. Asm / Hardware (http://eab.abime.net/forumdisplay.php?f=112)
-   -   68000 code optimisations (http://eab.abime.net/showthread.php?t=57587)

ross 27 April 2019 02:35

Quote:

Originally Posted by PeterJ (Post 1318413)
and it uses a lot of lsr #8 and Lsl #8 so the about is just perfect :)

For
lsr #8
the trick is similar:

Code:

    d0.w=xx00
    moveq  #0,d1
    ....

    move.w  d0,-(sp)
    move.b  (sp)+,d1
    ....
   
    d1.w=00xx

In this case you can use stack (so no spare A register and mem) but you need a D register and you must never touch his upper bits.

NorthWay 27 April 2019 06:51

[lsl #8]
My personal preference is to start the program with "clr.l -(sp)" and match it before end with "move.l (sp)+,d0", and then use pairs of
move.b dX,(sp)
move.w (sp),dX

PeterJ 27 April 2019 10:15

Quote:

Originally Posted by ross (Post 1318418)
For
lsr #8
the trick is similar:

Code:

    d0.w=xx00
    moveq  #0,d1
    ....

    move.w  d0,-(sp)
    move.b  (sp)+,d1
    ....
   
    d1.w=00xx

In this case you can use stack (so no spare A register and mem) but you need a D register and you must never touch his upper bits.


i just tried with $ff56 and the result was $ff

is it not only if you use movem.w that it clear or set the upper word depending of bit15?

ross 27 April 2019 11:21

Quote:

Originally Posted by NorthWay (Post 1318435)
[lsl #8]
My personal preference is to start the program with "clr.l -(sp)" and match it before end with "move.l (sp)+,d0", and then use pairs of
move.b dX,(sp)
move.w (sp),dX

:great
You just have to be careful not to use it in a nested routine so your sentence should be written "to start the subroutine with".


Quote:

Originally Posted by PeterJ (Post 1318443)
i just tried with $ff56 and the result was $ff

As is should (i've simply written d0=$xx00 because low bits are anyway lost so can be anything).
But from your next phrase is it not that you meant the
asr
instruction?
Quote:

is it not only if you use movem.w that it clear or set the upper word depending of bit15?
Regardless,
movem
deals with words (or longs) and never with bytes.

hooverphonique 29 April 2019 13:36

Quote:

Originally Posted by PeterJ (Post 1318413)
and it uses a lot of lsr #8 and Lsl #8 so the about is just perfect :)

If they are used in hot code, maybe the solution is to refactor the necessity for these shifts away completely ;)

NorthWay 14 August 2019 21:51

Quote:

Originally Posted by NorthWay (Post 1288346)
once upon a time there was a thing called the GNU(gcc?) super-optimizer

I found this reference to it: https://courses.cs.washington.edu/co...s/massalin.pdf

Photon 17 August 2019 01:08

Quote:

Originally Posted by NorthWay (Post 1338602)

A factor from my experience is that optimized C runs 10x slower than optimized Assembly, and that C++ cannot be fully reduced to C for an application. (This is up to about 68020/80386, where actually Pascal in some cases had a lower factor than C. Since the popularity of C, this may have changed, but not measured by me.)

Later, on-chip caches affected performance more than the number and time length of instructions, and this allowed utility applications to not be bogged down and reduce this factor.

But even after this hardware acceleration (circa 1990), applications such as games and demos would never use C (or C++) in time-critical sections for another half a decade, as we know.

It's true to this day that any high-level language (or one posing as such!) will always be beaten by a great margin by "simply" writing the program in Assembly. (The advantage of truly portable languages is of course the portability and less code to write, if you're not using macros.)

All this to make clear that there is no language level higher than Assembly that will ever generate as efficient (or small) code as writing it in Assembly :)

It's self-evident. But just to give factors for the performance loss paid. The compiler doesn't know what you're trying to do, so it can't deliver the perfect translation.

sparhawk 04 February 2020 16:19

Maybe there is a faster way to clear the upper word of a register?

Replace this (16 cycles):
Code:

    and.l  #$ffff,d0
With this (12 cycles):
Code:

    moveq  #0,d1
    move.w  d0,d1
    move.l  d1,d0

I try to avoid (if possible) the second move by arranging the registers appropriatly, in which case the count would go down to 8 cycles.

Also 12 Cycles but only one register needed:
Code:

    swap    d0
    clr.w  d0
    swap    d0


ross 04 February 2020 17:51

Quote:

Originally Posted by sparhawk (Post 1376516)
Maybe there is a faster way to clear the upper word of a register?

If you know for sure that's a positive value, you can
ext.l dx
(4 cycles :))

But usually I keep a register with the upper part zeroed out of the main loop and then move the data only for the lower part.

sparhawk 04 February 2020 17:53

Quote:

Originally Posted by ross (Post 1376531)
If you know for sure that's a positive value, you can
ext.l dx
(4 cycles :))


Yes, that woul dbe the obvious solution. :D But it depends, so in the general case, I can't know that.


I usually do a lot of prototyping in Easy68k and see if I can find faster solutions as it tells me the cycle count, which is IMO a great feature for that. :)

Antiriad_UK 21 February 2020 15:03

This is one I saw in another thread that made me scratch my head for a while is using add dx,dx to simultaneously test and clear a "flag". For example you have a loop where you are setting a flag from 0 to 1 if something occurred. Then at the end of the loop you check the flag to see if you need to loop again and reset the flag (sorting routine I did this in).

Instead of:
Code:

.loop:
        moveq        #0,d0                        ;reset flag
        ...
        ;If something occured, flag it
        moveq        #1,d0
        ...
        ;Do we need to loop again?
        tst.w        d0
        bne.s        .loop

Do this:
Code:

        moveq        #0,d0                        ;reset flag once
.loop:
        ...
        ;If something occured, flag it
        moveq        #-128,d0                ;set flag = $80 ($fffffff80)
        ...
        ;Do we need to loop again? Also reset flag
        add.b        d0,d0
        bcs.s        .loop

Can do the same thing with subq and bmi, but I liked the use of carry :)

hooverphonique 21 February 2020 15:50

Quote:

Originally Posted by Antiriad_UK (Post 1380512)
Code:

    moveq    #0,d0            ;reset flag once
.loop:
    ...
    ;If something occured, flag it
    moveq    #-128,d0        ;set flag = $80 ($fffffff80)
    ...
    ;Do we need to loop again? Also reset flag
    add.b    d0,d0
    bcs.s    .loop


I stared at this for a while without seeing how it would reset the flag (carry), but I suppose you meant "reset" in the sense of returning d0 to zero?

Pixelfill 21 February 2020 16:00

Quote:

Originally Posted by hooverphonique (Post 1380526)
I stared at this for a while without seeing how it would reset the flag (carry), but I suppose you meant "reset" in the sense of returning d0 to zero?

I may be wide of the mark here, but I'm guessing adding bytes -128 to -128 results in -256, therefore an overflow beyond a byte (carry) and also results in d0.b set to 00?
the key part I believe is not the add.b. but the fact that d0 contains $xxxxxx80 beforehand from the moveq

forgive me if I'm wrong as I'm just starting out.

Mike

Antiriad_UK 21 February 2020 16:05

Quote:

Originally Posted by hooverphonique (Post 1380526)
I stared at this for a while without seeing how it would reset the flag (carry), but I suppose you meant "reset" in the sense of returning d0 to zero?

Yes resets d0 to 0 so you can save a whole 4 cycles per loop:)

hooverphonique 21 February 2020 16:42

Quote:

Originally Posted by Pixelfill (Post 1380531)
I may be wide of the mark here, but I'm guessing adding bytes -128 to -128 results in -256, therefore an overflow beyond a byte (carry) and also results in d0.b set to 00?
the key part I believe is not the add.b. but the fact that d0 contains $xxxxxx80 beforehand from the moveq

Yes, you're right, and it's also where I arrived at, hence the last part of my previous comment :)


All times are GMT +2. The time now is 07:31.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.

Page generated in 0.05437 seconds with 11 queries