Recent

Author Topic: Did you know this cool if-then-else syntax ?  (Read 6269 times)

Basile B.

  • Guest
Did you know this cool if-then-else syntax ?
« on: November 27, 2014, 11:56:35 pm »
This afternoon i was reading some random things on Github
while I suddently found this syntax for writting an if-then-else statement:

Code: [Select]
program Project1;
begin
  randomize;
  case random(77) > 44 of
    true: writeln('mlsdfg54f');
    false: case random(43) < 12 of
      true: writeln('54sdfgikeks');
      false: writeln('okiqjksdf5er');
    end;
  end;
  readln;
end.

 :o , damn how can i never see it before ! (typed my first Pascal SLOC in 2006).
Did you know this syntax ?

By the way, if you want to monitor daily the new Pascal things on GH bookmark this GH search.
« Last Edit: November 27, 2014, 11:59:45 pm by Basile B. »

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Did you know this cool if-then-else syntax ?
« Reply #1 on: November 28, 2014, 12:09:17 am »
Yes i guess we should all know syntax of case structure. Written with IF isn't any more complicated

Code: [Select]
  if random(77) > 44 then writeln('mlsdfg54f')
  else if random(43) < 12 then writeln('54sdfgikeks')
  else writeln('okiqjksdf5er');

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Did you know this cool if-then-else syntax ?
« Reply #2 on: November 28, 2014, 12:09:28 am »
I would be interested to know if this
Code: [Select]
case boolVar of
  False: RunFalseRoutine;
  True: RunTrueRoutine;
end;
is more efficient than
Code: [Select]
case boolVar of
  True: RunTrueRoutine;
  False: RunFalseRoutine;
end;

i. e. does the compiler optimise such constructs however you write them, or can you 'help' the compiler by optimising what might otherwise be a sub-optimal case-variable order, by ordering case variables yourself manually? No doubt inspecting the machine code the compiler produces in the two cases would tell me, only I'm not sufficiently asm-literate to interpret it correctly.

MathMan

  • Sr. Member
  • ****
  • Posts: 325
Re: Did you know this cool if-then-else syntax ?
« Reply #3 on: November 28, 2014, 01:45:25 am »
I would be interested to know if this
Code: [Select]
case boolVar of
  False: RunFalseRoutine;
  True: RunTrueRoutine;
end;
is more efficient than
Code: [Select]
case boolVar of
  True: RunTrueRoutine;
  False: RunFalseRoutine;
end;

i. e. does the compiler optimise such constructs however you write them, or can you 'help' the compiler by optimising what might otherwise be a sub-optimal case-variable order, by ordering case variables yourself manually? No doubt inspecting the machine code the compiler produces in the two cases would tell me, only I'm not sufficiently asm-literate to interpret it correctly.

Looked it up for you - in essence the answer is yes and no :-)

All the following solely relates to the x86-64 microprocessors. In both cases the compiler seems to generate ("seems to" because it does on my system - FPC 2.6.4 64 bit on Win 7/64 bit)

Code: [Select]
longbench.pas:316                         case test of
0000000000444429 807df800                 cmpb   $0x0,-0x8(%rbp)
000000000044442D 7502                     jne    0x444431 <WRAPPERAND+33> // true: statement
000000000044442F eb47                     jmp    0x444478 <WRAPPERAND+104> // false: statement
longbench.pas:318                         true: lAnd( Op2, Size1<<6, Op1, Size1<<6, Op3, Size1<<6 );
0000000000444431 488b05b80f2600           mov    0x260fb8(%rip),%rax        # 0x6a53f0 <U_LONGBENCH_OP3>
... some rubbish deleted
0000000000444476 eb45                     jmp    0x4444bd <WRAPPERAND+173>
longbench.pas:317                         false: lAnd( Op2, Size1<<6, Op1, Size1<<6, Op3, Size1<<6 );
0000000000444478 488b05710f2600           mov    0x260f71(%rip),%rax        # 0x6a53f0 <U_LONGBENCH_OP3>
... some rubbish deleted

The interesting part are the first three lines of asm. The compiler compares for "false" (the "cmpb   $0x0,-0x8(%rbp)" line) and if the boolean value is not "false" it jumps to the "true" part (the "jne    0x444431 <WRAPPERAND+33>" line). If the value is "false" however the processor skips this instruction and jumps to the "false" part (this is the statement in the third asm line).

To understand what this means in practice we need detour into processor architecture a bit. The x86-64 processors try to optimize process flow via branch prediction. This uses what is called a branch target buffer where conditions of recently taken branches are stored and the processor decides, based on this history, whether a branch will probably been taken or not. A branch misprediction leads to a stall in the pipeline and some serious delay in execution. The whole prediction works pretty damn well for the newer x86-64 processors for code that is repetitively executed (inside a small loop) and does not contain more than a certain number of branches.

What does this mean for you:

 * if you have this kind of branch within a loop and you know which alternative is more likely then put the more likely into the "true" part
 * if you have this kind of branch in a continuous code part that is rarely executed put the less likely into the "true" part

Does that answer your question?

Kind regards,
MathMan

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Did you know this cool if-then-else syntax ?
« Reply #4 on: November 28, 2014, 09:42:39 am »
Does that answer your question?

Yes, if you are saying that optimisation of case statements is related only to the previous case selection history and the relative likelihoods of any future selections; and that the physical ordering of case variables  in the source (e. g. by ordinal priority) is immaterial.

MathMan

  • Sr. Member
  • ****
  • Posts: 325
Re: Did you know this cool if-then-else syntax ?
« Reply #5 on: November 28, 2014, 11:03:54 am »
Does that answer your question?

Yes, if you are saying that optimisation of case statements is related only to the previous case selection history and the relative likelihoods of any future selections; and that the physical ordering of case variables  in the source (e. g. by ordinal priority) is immaterial.

Yes - it looks like it. Though I haven't analysed case statements with multiple selections yet but in case of the analysed boolean one your summary is spot on.

MathMan

  • Sr. Member
  • ****
  • Posts: 325
Re: Did you know this cool if-then-else syntax ?
« Reply #6 on: November 28, 2014, 12:28:45 pm »
Does that answer your question?

Yes, if you are saying that optimisation of case statements is related only to the previous case selection history and the relative likelihoods of any future selections; and that the physical ordering of case variables  in the source (e. g. by ordinal priority) is immaterial.

I am awfully sorry but I have to modify my previous statement a bit <sigh>. My only excuse is that it was late yesterday and I had forgotten that my project settings disabled optimization (had set it to O0). Did the analysis again though with O3 enabled and also looked into with a fan-out of 4 or 8 selections to understand whats happening there.

The compiler still generates the same code, regardless of how you order the cases - but the code itself is a bit different. However the suggestion I made regarding the boolean case still holds. For cases with a fan-out of 4 I analysed

Code: [Select]
  case ByteVar of
    0: DoNull();
    1: DoOne();
    2: DoTwo();
    3: DoThree();
  end;

Regardless of the ordering in the case statement the compiler generates code that first tests for 0 and branches accordingly, then 1, then 2 and finally 3. My advise in this case would be to associate the case with most probability to the lowest numeric selection - if this can be done easily. That is if you have to do substantial pre-computation to get to this association simply stick with what you have.

The same holds for fan-out 8 where the chain of branches is simply extended accordingly by the compiler - but still proceeding from low to high.

Regards,
MathMan

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11458
  • FPC developer.
Re: Did you know this cool if-then-else syntax ?
« Reply #7 on: November 28, 2014, 01:38:32 pm »

Obfuscated pascal contests are always fun!

Code: [Select]

const falsetrue:array[boolean] of string =('okiqjksdf5er','54sdfgikeks');

[program Project1;
begin
  randomize;
  case random(77) > 44 of
    true: writeln('mlsdfg54f');
    false: writeln(falsetrue[random(43) < 12]);
  end;
  readln;
end.
[code]

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: Did you know this cool if-then-else syntax ?
« Reply #8 on: November 28, 2014, 06:34:09 pm »
This needs IsTrue() and IsFalse() from BoolFactory unit  >:D

Bart

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 1186
    • Burdjia
Re: Did you know this cool if-then-else syntax ?
« Reply #9 on: December 02, 2014, 11:53:00 am »
I've found that "CASE" stuff instead "IF" but, after explanation by MathMan I still not see the difference.  I mean, it explains two different "CASE"  but not difference with "IF"...
Are you interested in game programming? Join the Pascal Game Development community!
Also visit the Game Development Portal

eny

  • Hero Member
  • *****
  • Posts: 1634
Re: Did you know this cool if-then-else syntax ?
« Reply #10 on: December 02, 2014, 12:25:14 pm »
This afternoon i was reading some random things on Github
while I suddently found this syntax for writting an if-then-else statement:
Other recommended reading material: http://lazarus-ccr.sourceforge.net/fpcdoc/ref/ref.html
All posts based on: Win10 (Win64); Lazarus 2.0.10 'stable' (x64) unless specified otherwise...

 

TinyPortal © 2005-2018