Possibly better loop construct, also labels+goto important and on the fly compiler idea.

Bernhard Schornak schornak at web.de
Fri Nov 1 00:53:59 CET 2013


Skybuck Flying wrote:


 >> Because it's logical.
 >
 > "
 > What is logical?
 > "
 >
 > To put the exit condition at the bottom is logical.


As "logical" as to put it anywhere else inside the loop body. As long as we write code
on machine language level, we are asked to choose the most efficient instruction chain
we can find. The decision where to place which instructions is up to the programmers -
not to a counter-productive "Universal Law".


 > The exit condition glues the loop to the code that will be executed next which is also at the bottom.
 >
 > Example:
 >
 > Loop
 >
 > NextCode


Yes. As you should know, jump targets should be aligned to 32 byte boundaries to avoid
prefetch stalls. Hence, it is absolutely illogical to let a loop run into a set of NOP
instructions at the bottom of the loop's body. Therefore, we had to end each loop with
a jump to the next label to avoid the execution of a couple of extra NOP instructions.
This is as illogical as the attempt to declare some artificial restrictions as the new
Non-Plus-Ultra of programming.


 > Placing the exit ondition near next code makes more sense at least in situation where I was
 > programming.
 >
 > I will give you an example:
 >
 >
 >
 > LoopBegin( Step = 10 )
 >
 >     if ButtonExists then
 >     begin
 >         ClickButton()
 >     end;
 >
 > LoopEnd( ButtonClicked )
 >
 > Execute next code...
 >
 > This loop waits for the button to appear, once it's found it is clicked and then the loop exits to
 > continue the next code.
 >
 > Putting this exit condition on the top makes no sense.


Ever thought about how a compiler might translate this construct? Here are 2 partially
optimised results:

ButtonExists  = bit 0 in RCX
ButtonClicked = bit 1 in RCX

       ...
       movl  $0x0A, %ebp
       testl $0x01, %ecx        # does button exist?
       je    1f
       jmp   0f

       .p2align 5,,31
     0:decl  %ebp
       je    1f
       call  _ClickButton
       jmp   0b

       .p2align 5,,31
      1:orl  $0x02, %ecx        # button was clicked ten times...
       ...


Alternative:

       ...
       movl  $0x0A, %ebp
       testl $0x01, %ecx        # does button exist?
       je    1f
       jmp   0f

       .p2align 5,,31
     0:call  _ClickButton
       decl  %ebp
       jne   0b
       jmp   1f

       .p2align 5,,31
      1:orl  $0x02, %ecx        # button was clicked ten times...
       ...


The code with the conditional branch at top is faster than the alternative code,
because putting calls at places used as branch target, even if properly aligned,
is punished with some penalty cycles. As the loop ends at the bottom, we have to
insert a second jump to bypass the second set of NOPs.

Placing an exit condition at the top possibly looks odd for HLL programmers, but
it's faster in many cases. Placing all exit conditions at the bottom of the loop
body can never be faster, but often will be the slower solution.

You should translate your HLL constructs into simple machine language before you
start to declare "Universal Laws" which are none.

I am still wondering why you post to alt.lang.asm if you do not accept that your
proposals are analysed and their flaws are revealed. ;)


BTW: If this button ever existed, it'll exist throughout the runtime of the loop
without disappearing.  Hence, it is not necessary to query its existence in each
iteration, because it costs a lot of precious time. The best solution is the one
above - check if the button exists, then start the loop.


Greetings from Augsburg

Bernhard Schornak




More information about the Python-list mailing list