FP compiler optimization lazarus / 62-General ---------------------------------------------------------------------- BobS · 2015-10-20 02:19 I was playing around looking to see how various code snippets are optimized by the compiler (like a *2 becoming a shift left--seeing is believing ). I looked at the assembly output for this code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program Project1;var x: double; //or any float type begin  x:=x*0.5;  x:=x/2.0;end.     These lines do the same thing, but the first statement generates a fmul while the second statement generates fdivr which is far less efficient (latency 4 vs 11-25).  I tried playing with compiler optimizer directives but never noticed the second statement being anything but a fdiv so am I doing something wrong with the optimization directives or is this something that might be added to the compiler in the future?  I know it doesn't matter for this trivial example, but for code clarity, like when following formulas, it would sometimes be nice to write the division and let the compiler do the optimizing.  Or is this a non-trivial compiler optimization since you'd have to calculate the reciprocal at the full precision of the type used? ---------------------------------------------------------------------- Leledumbo · 2015-10-20 03:37 This is what my x86_64-linux FPC 3.1.1 produce (no optimization option used at all): Code: ASM  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i         # Register xmm0 allocated# [5] x:=x*0.5;        movsd   U_$P$PROJECT1_$$_X,%xmm0        mulsd   _$PROJECT1$_Ld1,%xmm0        # Register xmm0 released        movsd   %xmm0,U_$P$PROJECT1_$$_X        # Register xmm0 allocated# [6] x:=x/2.0;        movsd   U_$P$PROJECT1_$$_X,%xmm0        mulsd   _$PROJECT1$_Ld1,%xmm0        # Register xmm0 released        movsd   %xmm0,U_$P$PROJECT1_$$_X....section .rodata.n__$PROJECT1$_Ld1        .balign 8.globl  _$PROJECT1$_Ld1_$PROJECT1$_Ld1:# value: 0d+5.0000000000000000E-001        .byte   0,0,0,0,0,0,224,63 So both produce the same code. -O2 just moves the variable allocation from stack to register, thus the instruction becomes only mulsd against xmm0. The same $PROJECT1$_Ld1 is used. ---------------------------------------------------------------------- Thaddy · 2015-10-20 07:39 There are three things to note here: 1. First you should choose your target processor. FPC defaults to a conservative one. 2. Second you should choose your FPU, again, FPC defaults to a conservative one 3. After that, you should choose your optimization level. My choices are mostly conservative too, but a lot less so than FPC does by default: for i386 with trunk I do for example: -CpPENTIUMM -CfSSE3 -O3 -al which generates: Code: [Select]_main: # Var x located in register xmm0 # [asmtest.pp] # [5] begin call fpc_initializeunits xorpd %xmm0,%xmm0 # [6] x:=x*0.5; mulsd _$ASMTEST$_Ld1,%xmm0 # Var x located in register xmm0 # [7] x:=x/2.0; mulsd _$ASMTEST$_Ld1,%xmm0 # Var x located in register xmm0 # [8] end. call fpc_do_exit ret As you can see: highly optimized 386 code. And not a division in sight. ---------------------------------------------------------------------- BobS · 2015-10-20 20:04 Ah good that's what I was wondering.  Just the O3 alone is not enough.  Looks much nicer .  Now for some more playing around. Thanks for replies. ---------------------------------------------------------------------- Ñuño_Martínez · 2015-10-23 11:26 Wow!  That may explain why my applications are a lot slower than expected. I was using the wrong optimization options! Thank-you, now I can compete with those that use C and C++. Question is, which microprocessor do you recommend for a conservative target?  I suppose that PentiumIII would be a good option for 32bit, but I have no idea about 64bit. ---------------------------------------------------------------------- Thaddy · 2015-10-23 14:35 That would be fine and very very conservative. Intel CORE would cover most of the installed base, though. That includes AMD's of the period (slightly later, sometimes) So -CpPENTIUM4 -CfSSE2 is also conservative enough. The essential floating point speed-up comes from SSE+ and FPC is pretty good with that. Note, however that for high precision calculations X87 is still the way to go (80bit vs 64bit for SSEX) at the cost of speed. ---------------------------------------------------------------------- BobS · 2015-10-24 00:37 So should I recompile the libraries with optimization settings, especially math, or are they otherwise already pretty well optimized? ---------------------------------------------------------------------- Leledumbo · 2015-10-24 04:10 Quote from: BobS on October 24, 2015, 02:37:12 amSo should I recompile the libraries with optimization settings, especially math, or are they otherwise already pretty well optimized? The default is -O2 only AFAIK. Not everybody has SSExx powered processors so it makes the distribution less portable if units are compiled with processor specific optimizations. ---------------------------------------------------------------------- BobS · 2015-10-24 06:20 Sorry, what I was really trying to get at: is there much benefit in these libraries, particularly system and math to recompiling with these options (PentiumM SSE3 --or actually X87 in my current program since it uses extended type). I guess I could do some timing loops and see but thought this might be generally known. ---------------------------------------------------------------------- Thaddy · 2015-10-24 09:08 Quote from: Leledumbo on October 24, 2015, 06:10:36 amQuote from: BobS on October 24, 2015, 02:37:12 amSo should I recompile the libraries with optimization settings, especially math, or are they otherwise already pretty well optimized? The default is -O2 only AFAIK. Not everybody has SSExx powered processors so it makes the distribution less portable if units are compiled with processor specific optimizations. I am not aware of any mainstream processor on the market without at least sse2. The last ones to appear were the VIA C7's and even that was eight years ago. The rest is closer to 15 years including almost all x86_64 variants after ATHLON. So SSE2 is very conservative. Platforms not supporting SSE2 should be considered legacy special case and warrant "special case" compilation. The situation for embedded is slightly different, but specialty. ---------------------------------------------------------------------- Thaddy · 2015-10-24 09:16 Quote from: BobS on October 24, 2015, 08:20:16 amSorry, what I was really trying to get at: is there much benefit in these libraries, particularly system and math to recompiling with these options (PentiumM SSE3 --or actually X87 in my current program since it uses extended type). I guess I could do some timing loops and see but thought this might be generally known. Yes, there are real benefits in compiling the RTL/FCL with SSE2 or 3 enabled and with a more modern instuction set than 80386. To the compiler itself it makes little or no difference, perhaps. As my position regarding SSE2 as a minimum, see my answer to Leledumbo. Anything mainstream for PC platforms newer than 15 years old has at least SSE2, except the VIA, but that is really not mainstream itself and is also already 8 years old. You decide . Note that 64 bit SSEX compiled code also supports the keyword extended, only aliased to 64 bit. Only 32bit compiled code uses the x87 fp instruction set by default afaik. ---------------------------------------------------------------------- Leledumbo · 2015-10-24 19:51 Quote from: Thaddy on October 24, 2015, 11:08:52 amI am not aware of any mainstream processor on the market without at least sse2. The last ones to appear were the VIA C7's and even that was eight years ago. The rest is closer to 15 years including almost all x86_64 variants after ATHLON. So SSE2 is very conservative. Platforms not supporting SSE2 should be considered legacy special case and warrant "special case" compilation. The situation for embedded is slightly different, but specialty. I guess you could say that to FPC team, so the installer ships precompiled units with SSE2 or something. ---------------------------------------------------------------------- BobS · 2015-10-24 23:15 Thanks all, I'll give everything a recompile then.  I was also thinking along the lines, of who has a 32bit processor these days if they are using say the Windows version of Lazarus or probably the Mac version too.  Might be time to consider moving up in the world a bit.  I see that Microsoft C++ has had SSE2 as default since 2012--got to make those benchmarks look good. Actually I was also thinking about the aliasing problem of extended and decided the simplest thing is to have two versions Laz/FPC one compiled with SSE3 (introduced in 2004 has it been that long?) and the other with X87 for when I need 80 bit numbers.  Anyone who wants to run my code on something else will be free to compile it themselves .  I've defiantly learned some important stuff here.  Also made me look at what the various SSEx levels offer which I don't think I've done since they were introduced, some interesting stuff I'd forgotten about. ---------------------------------------------------------------------- Leledumbo · 2015-10-25 06:25 If it's for your own computer or at least you know your target computers are recent enough, consider using the best switch you can get. I, for example, use -O3 -CpCOREAVX2 -OpCOREAVX2 -CfAVX2 for my FPC and Lazarus installation. This gives the best code on my machine. There's -O4, but as been said, it's for optimizations whose side effects are not yet known, better not to use it. ---------------------------------------------------------------------- BobS · 2015-10-26 02:49 Glad you said that about -O4 I was thinking about seeing what it did.  For now seems best left alone after all this time I'm still occasionally stumbling across some Pascal fundamental I've forgotten...so don't want to introduce extra instability . According to the -i option I'm not seeing anything beyond Pentium4 or PentiumM plus SSE3 though I am running a 5830K processor so I guess that's the best available now. I also seem to recall reading that > -O2 can cause debugger problems which complicates this even more (if I want to be able to step into the libraries which can be handy sometimes). ---------------------------------------------------------------------- Leledumbo · 2015-10-26 05:14 Quote from: BobS on October 26, 2015, 03:49:43 amI also seem to recall reading that > -O2 can cause debugger problems which complicates this even more (if I want to be able to step into the libraries which can be handy sometimes). I'm amazed if you can still debug with -O2. I only define 2 extreme options: debug = -O- -XS release = -O -Op -Cp -Cf -g- -CX -XXs Even if -O1 is advertised as debugger friendly, non-optimized code gives best debugging experience. ---------------------------------------------------------------------- BobS · 2015-10-26 20:11 Good to know.  When I complied the trunk I hadn't set any optimize so I didn't run into any problems it just seems like I've read about not going above O2 but anyway I'll keep it at no optimizations for now thanks for heads up.  Fortunately it actually only takes a few minutes to recompile the whole thing on my system, gotta love those SSD's. ---------------------------------------------------------------------- rtusrghsdfhsfdhsdfhsfdhs · 2015-10-27 17:04 Quote from: Leledumbo on October 26, 2015, 06:14:30 amQuote from: BobS on October 26, 2015, 03:49:43 amI also seem to recall reading that > -O2 can cause debugger problems which complicates this even more (if I want to be able to step into the libraries which can be handy sometimes). I'm amazed if you can still debug with -O2. I only define 2 extreme options: debug = -O- -XS release = -O -Op -Cp -Cf -g- -CX -XXs Even if -O1 is advertised as debugger friendly, non-optimized code gives best debugging experience. Can you give an example of your actual debug and release? best avaliable on trunk and for intel? ---------------------------------------------------------------------- Leledumbo · 2015-10-28 00:28 Quote from: Fiji on October 27, 2015, 06:04:50 pmbest avaliable on trunk and for intel? Debug: -Cirot -gw2 -godwarfsets -gl -gh Release: -CX -Xs -XX -O3 -OpCOREAVX2 -CpCOREAVX2 -CfAVX2