Results 1 to 8 of 8

Thread: GCC: is there an optimization for the switch (...)?

  1. #1
    Member lz77's Avatar
    Join Date
    Jan 2016
    Location
    Russia
    Posts
    176
    Thanks
    60
    Thanked 16 Times in 12 Posts

    GCC: is there an optimization for the switch (...)?

    In Delphi 7 such a trick is possible with the calculation of the jump address in the case statement. For example, there is case statement by prefix = 0,1,2,3 when LZ decompressing (but it breaks optimization):

    Code:
    var
     cm0: array[0..3] of dword;
    ...
    
    asm
    mov dword [cm0],offset m0
    mov dword [cm0+4],offset m1
    mov dword [cm0+8],offset m2
    mov dword [cm0+12],offset m3
    end;
    
    <Decompressing loop starts>
    
    asm
    mov eax,prefix
    jmp offset cm0+eax*4
    end;
    
    
    m0:    offs:=...; goto 1000;
    m1:    offs:=...; goto 1000;
    m2:    offs:=...; goto 1000;
    m3:    offs:=...;
    
    1000:
    Is it possible in C to calculate the addresses of the labels and make such a jump? Or does the translator do it itself?

  2. #2
    Member
    Join Date
    Aug 2016
    Location
    USA
    Posts
    73
    Thanks
    17
    Thanked 23 Times in 18 Posts
    I think most modern compilers can do that optimization; if you're interested to investigate, I can't recommend https://godbolt.org/ highly enough.

    Here is an dumb example with a switch statement: https://godbolt.org/z/hK634x

    Notice the indirect jump straight into the case: jmp [QWORDPTR.L4[0+rdi*8]]


  3. Thanks:

    lz77 (9th February 2021)

  4. #3
    Administrator Shelwien's Avatar
    Join Date
    May 2008
    Location
    Kharkov, Ukraine
    Posts
    4,135
    Thanks
    320
    Thanked 1,397 Times in 802 Posts
    Its possible, but its a gcc extension: https://gcc.gnu.org/onlinedocs/gcc/L...as-Values.html
    clang/gcc/IntelC do support it: https://godbolt.org/z/s4EboW
    VS only via inline asm: https://stackoverflow.com/questions/...of-labels-msvc

  5. Thanks:

    lz77 (9th February 2021)

  6. #4
    Member lz77's Avatar
    Join Date
    Jan 2016
    Location
    Russia
    Posts
    176
    Thanks
    60
    Thanked 16 Times in 12 Posts
    In my decompressor GCC does not use jmp label to optimize switch, only conditional jmps. I tried to use goto *labels[pref], but it decreases speed on 40%...

    Now my program decompresses enwik8 in 0.328 sec. vs. 0.234 sec. by zstd (40% worse in decompression time, 1.5% better in ratio). I will do some optimizations in algorithm, then will port it from C to asm to see its power. After that I will do the same with my compressor (Delphi 7 -> C -> asm).
    Last edited by lz77; 12th February 2021 at 19:30.

  7. #5
    Member
    Join Date
    Aug 2016
    Location
    USA
    Posts
    73
    Thanks
    17
    Thanked 23 Times in 18 Posts
    Whether GCC will use a jump table or not depends on many details, including the exact arch you compile for. Jump table might be preferred on older Intel microarchs, but not on newer ones, etc. There are three ways to control things, and you can experiment with them if you really want (full list at https://gcc.gnu.org/onlinedocs/gcc/O...e-Options.html) I think the spacing (gaps) in case statements and the presence of default: cases can also affect the decision to use the optimization. I really wish more compilers had #pragma statements to locally tweak such decisions, but they can also be fragile optimizations. I remember trying to get msvc to produce a conditional move at one point, and it worked great for Penryn, but later on, for Haswell, on the same tests was worse than eating a branch.

    Adding --param case-values-threshold=10 to the example I linked above disabled the jump table;

    You can pass these to gcc with --param name=value

    case-values-threshold The smallest number of different values for which it is best to use a jump-table instead of a tree of conditional branches. If the value is 0, use the default for the machine.

    jump-table-max-growth-ratio-for-size The maximum code size growth ratio when expanding into a jump table (in percent). The parameter is used when optimizing for size.

    jump-table-max-growth-ratio-for-speed The maximum code size growth ratio when expanding into a jump table (in percent). The parameter is used when optimizing for speed.
    Last edited by Stefan Atev; 14th February 2021 at 00:42. Reason: spacing

  8. Thanks:

    lz77 (13th February 2021)

  9. #6
    Member lz77's Avatar
    Join Date
    Jan 2016
    Location
    Russia
    Posts
    176
    Thanks
    60
    Thanked 16 Times in 12 Posts
    I've added
    --param jump-table-max-growth-ratio-for-speed=100
    ​to command line, but saw the message:
    cc1.exe: error: invalid --param name 'jump-table-max-growth-ratio-for-speed'

  10. #7
    Member
    Join Date
    Jul 2018
    Location
    Russia
    Posts
    41
    Thanks
    0
    Thanked 4 Times in 3 Posts
    Quote Originally Posted by lz77 View Post
    ... , but saw the message:
    cc1.exe: error: invalid --param name 'jump-table-max-growth-ratio-for-speed'

    In my opinion, this is a great reason to stop doing such an unnatural thing as using GCC on Windows.

    UPD: even if on Linux there is the same message
    Last edited by e8c; 13th February 2021 at 18:26.
    Dvizh must go Dvizh, no open source - no Dvizh.

  11. #8
    Administrator Shelwien's Avatar
    Join Date
    May 2008
    Location
    Kharkov, Ukraine
    Posts
    4,135
    Thanks
    320
    Thanked 1,397 Times in 802 Posts
    Try it like this: "g++ --param=jump-table-max-growth-ratio-for-speed=10 1.cpp"
    Also see the bottom of https://gcc.gnu.org/onlinedocs/gcc/O...e-Options.html - there may be other useful parameters.

Similar Threads

  1. New members got idea? Dead Man's Switch IT.
    By Trench in forum The Off-Topic Lounge
    Replies: 0
    Last Post: 19th September 2020, 07:28
  2. Replies: 0
    Last Post: 18th June 2020, 12:53
  3. gcc 9.1.1 released
    By Shelwien in forum The Off-Topic Lounge
    Replies: 2
    Last Post: 15th July 2019, 20:38
  4. GCC 4.6 faster than previous GCC, faster than LLVM
    By willvarfar in forum The Off-Topic Lounge
    Replies: 2
    Last Post: 15th November 2010, 16:09
  5. GCC 4.4.1 for Windows
    By Bulat Ziganshin in forum The Off-Topic Lounge
    Replies: 1
    Last Post: 16th January 2010, 00:39

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •