Not a REAL wtf, just wondering why it was coded this way...



  • Not a REAL wtf, just wondering why it was coded this way...

    NB: (Megs is an int declared above)

                    if (_InitSize)
                    {
                        long length = 1024;
                        length = length * 1024;
                        length = length * Megs;
                        fs.SetLength(length);
                    }

     

    surely this would suffice;

                    if (_InitSize)
                    {
                        long length = 1024 * 1024 * Megs;
                        fs.SetLength(length);
                    }

     or (as 1024 * 1024 is constant)

                        long length = 1048576 * Megs
     

     

    The only reason I can think of the original syntax was for readability. I found it in a post about improving performance of certain operations (and this was part of his suggested 'best way').

     

    cheers 

     



  • long length  = Megs << 20; 

    would IMO be the best option. I have no idea why someone would want to write it like in the OP. 



  • this wouldn't effect the performance at all.  Any compiler with any optimization will optimize both of those to constants.



  • Could be brain fart.

    I sometimes write a little bit of code, come back the next day, see the stupidest code ever and wonder what the hell I was smoking.



  • An average compiler would probably optimize "1024 * 1024 * Megs" to "1048576

    • Megs" and maybe even to "Megs << 20" but I'm not sure if it would detect the original case. (I know nothing about compiler design though). So maybe someone desperately avoided compiler optimizations? :)


  • @PSWorx said:

    An average compiler would probably optimize "1024 * 1024 * Megs" to "1048576 * Megs" and maybe even to "Megs << 20" but I'm not sure if it would detect the original case. (I know nothing about compiler design though). So maybe someone desperately avoided compiler optimizations? :)

    Modern compiler architecture would pick it up just fine. gcc 3.x and older, or msvc, might not. 



  • @asuffield said:

    @PSWorx said:

    An average compiler would probably optimize "1024 * 1024 * Megs" to "1048576

    • Megs" and maybe even to "Megs << 20" but I'm not sure if it would detect the original case. (I know nothing about compiler design though). So maybe someone desperately avoided compiler optimizations? :)

    Modern compiler architecture would pick it up just fine. gcc 3.x and older, or msvc, might not. 

     I would be suprised if gcc 3.x didn't optimize it.  A very simple data flow analysis would produce that constant folding.
     



  • @tster said:

    @asuffield said:

    @PSWorx said:

    An average compiler would probably optimize "1024 * 1024 * Megs" to "1048576

    • Megs" and maybe even to "Megs << 20" but I'm not sure if it would detect the original case. (I know nothing about compiler design though). So maybe someone desperately avoided compiler optimizations? :)

    Modern compiler architecture would pick it up just fine. gcc 3.x and older, or msvc, might not. 

     I would be suprised if gcc 3.x didn't optimize it.  A very simple data flow analysis would produce that constant folding.

    You would indeed be surprised as just how bad the pre-ssa dataflow code was. 4.0 replaced a system that's about 10 years old with a modern one (thankfully, that's almost the last of the disastrously obsolete code eliminated). I can't be bothered to root out an old copy of gcc and find out if it actually could figure out this particular case, but it used to have great difficulty with non-trivial code motion/constant folding optimisations.



  • @asuffield said:

    You would indeed be surprised as just how bad the pre-ssa dataflow code was. 4.0 replaced a system that's about 10 years old with a modern one (thankfully, that's almost the last of the disastrously obsolete code eliminated). I can't be bothered to root out an old copy of gcc and find out if it actually could figure out this particular case, but it used to have great difficulty with non-trivial code motion/constant folding optimisations.

    int main(void)
    {
     9a0:   53                      push   %rbx
       int foo = 1024;
       float bar;
    
       bar = foo * 2;
       foo = (4 >> 1) * (foo * foo);
       foo %= (int)(bar * 3);
       bar -= foo / bar;
       foo *= bar;
    
       printf("%d\n", foo);
     9a1:   48 8d 3d 34 01 00 00    lea    308(%rip),%rdi
     9a8:   be 00 f8 3f 00          mov    $0x3ff800,%esi    # 4192256
     9ad:   48 83 ec 10             sub    $0x10,%rsp
     9b1:   48 8b 1d 30 06 10 00    mov    1050160(%rip),%rbx
     9b8:   48 8b 03                mov    (%rbx),%rax
     9bb:   48 89 04 24             mov    %rax,(%rsp)
     9bf:   31 c0                   xor    %eax,%eax
     9c1:   e8 c2 fe ff ff          callq  888 <printf@plt>
    

    gcc (GCC) 3.4.6 (Gentoo Hardened 3.4.6-r2 p1.5, ssp-3.4.6-1.0, pie-8.7.10)

    int main(void)
    {
    100003d4:       94 21 ff f0     stwu    r1,-16(r1)
    100003d8:       7c 08 02 a6     mflr    r0
    100003dc:       90 01 00 14     stw     r0,20(r1)
       int foo = 1024;
       float bar;
    
       bar = foo * 2;
       foo = (4 >> 1) * (foo * foo);
       foo %= (int)(bar * 3);
       bar -= foo / bar;
       foo *= bar;
    
       printf("%d\n", foo);
    100003e0:       3c 60 10 00     lis     r3,4096
    100003e4:       3c 80 00 3f     lis     r4,63          # r4 = 16
    100003e8:       38 63 06 0c     addi    r3,r3,1548
    100003ec:       60 84 f8 00     ori     r4,r4,63488    # 63488 | (r4 << 16) = 4192256
    100003f0:       4c c6 31 82     crclr   4*cr1+eq
    100003f4:       48 00 01 4d     bl      10000540 <init_dummy+0x20>
    

    GCC 2.95.3 on PPC



  • Interesting. How would that example look with the latest GCC?



  • @PSWorx said:

    Interesting. How would that example look with the latest GCC?

    I don't have the latest GCC (4.2.0?) installed, but I do have 4.1.2. The x86_64 code generated by 4.1.2 is exactly the same as that generated by 3.4.6 (with SSP and PIE turned off):

      4006a4:       be 00 f8 3f 00          mov    $0x3ff800,%esi
      4006a9:       bf ac 07 40 00          mov    $0x4007ac,%edi
      4006ae:       31 c0                   xor    %eax,%eax
      4006b0:       e8 eb fe ff ff          callq  4005a0 <printf@plt>
    


  • @anonymouse123 said:

    @PSWorx said:
    Interesting. How would that example look with the latest GCC?
    I don't have the latest GCC (4.2.0?) installed, but I do have 4.1.2. The x86_64 code generated by 4.1.2 is exactly the same as that generated by 3.4.6 (with SSP and PIE turned off):

    Which isn't hugely surprising, since it does happen to be the minimal form. It would be more interesting to see what happens on powerpc now, as that code from 2.95 doesn't look anywhere close to the minimal form to me.

    Earlier versions of gcc are also increasingly likely to generate worse code - basically, it used to use a huge pile of heuristics and guesses instead of a reliable algorithm, so as the source becomes more complicated and the version becomes older, the generated code becomes less optimal. As of 4.0, gcc should find the optimum solution to all problems of this type, including ones threaded with conditionals and loops.



  • Stuff like this makes me wonder how I can trust the code I've written.


Log in to reply