-
Notifications
You must be signed in to change notification settings - Fork 0
Optimization options
Enabling compiler optimizations is actually pretty easy. The process consists of passing one or two additional flags to the compiler. Here's a list of common optimization options.
-
-O0: no optimizations whatsoever -
-O1: simple optimizations -
-O2: conservative (intra-procedural) optimizations -
-O3: aggressive (inter-procedural) optimizations -
-g: retain constructs that are intended for debugging, such as assertions -
-Og: shorthand for-O1 -g
By default, ecsc will use the -Og optimization level. Once any of the above optimization options are given, ecsc will no longer make this assumption. Therefore, providing only -O0/-O1/-O2/-O3 gives ecsc permission to remove debugging code (since -g was not given). Analogously, using -g only will keep ecsc from removing debugging code, but it will also keep ecsc from applying any optimizations, as no optimization level was given.
Here's a short example that compares the different optimization options. Your mileage may vary, as run-time performance depends on lots of different factors: your hardware, the JIT, the program that is compiled, etc.
tests/cs/fractal$ mkdir -p bin
tests/cs/fractal$ mcs Fractal.cs -out:bin/Fractal.exe
tests/cs/fractal$ time mono bin/Fractal.exe
Mandelbrot:6839743 Julia:6449238
real 0m0.224s
user 0m0.220s
sys 0m0.000s
tests/cs/fractal$ ecsc Fractal.cs -platform clr -Og
tests/cs/fractal$ time mono bin/Fractal.exe
Mandelbrot:6839743 Julia:6449238
real 0m0.215s
user 0m0.208s
sys 0m0.004s
tests/cs/fractal$ ecsc Fractal.cs -platform clr -O2
tests/cs/fractal$ time mono bin/Fractal.exe
Mandelbrot:6839743 Julia:6449238
real 0m0.215s
user 0m0.212s
sys 0m0.004s
tests/cs/fractal$ ecsc Fractal.cs -platform clr -O3
tests/cs/fractal$ time mono bin/Fractal.exe
Mandelbrot:6839743 Julia:6449238
real 0m0.107s
user 0m0.104s
sys 0m0.000s
It's interesting to see that mcs's results are quite similar to ecsc's for the -Og and -O2 builds. But the -O3 build clearly blows all other executables out of the water in terms of performance.
The versions of the tools that were used to produce these measurements are listed below. I used a local build of ecsc, which explains why its version number looks funny. Almost all of ecsc's optimizations are implemented by Flame, though. So you can just look at Flame's version number instead.
$ mono --version
Mono JIT compiler version 4.6.2 (Stable 4.6.2.16/ac9e222 Tue Jan 3 11:48:26 UTC 2017)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
TLS: __thread
SIGSEGV: altstack
Notifications: epoll
Architecture: amd64
Disabled: none
Misc: softdebug
LLVM: supported, not enabled.
GC: sgen
$ mcs --version
Mono C# compiler version 4.6.2.0
$ ecsc --version
ecsc version 1.0.6219 (based on Flame 0.9.2)
EC# parser: Loyc 2.4.3
Platform: Unix 4.8.0.32
Console: xterm-256color
You can check for new releases at https://github.com/jonathanvdc/ecsc/releases
Thanks for using the EC# compiler! Have fun writing code.
ecsc: nothing to compile: no input files
If you want ecsc to explain which (-O3) optimizations it performed, then you can use the -Rinline and -Rscalarrepl, which turn on optimization remarks for the inlining and scalar replacement of aggregates pass, respectively.
tests/cs/fractal$ ecsc Fractal.cs -platform clr -O3 -Rinline -Rscalarrepl
Fractal.cs:94:21: pass remark: inlined direct call to 'complex'. [-Rinline]
complex num = new complex(x, y);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Fractal.cs:99:33: pass remark: inlined direct call to 'square'. [-Rinline]
accum = accum.square();
^~~~~~~~~~~~~~
Fractal.cs:100:25: pass remark: inlined direct call to '+'. [-Rinline]
accum += num;
^~~~~~~~~~~~
Fractal.cs:101:29: pass remark: inlined direct call to 'sqabs'. [-Rinline]
if (accum.sqabs() > limit)
^~~~~~~~~~~~~
Fractal.cs:85:32: pass remark: replaced 7 aggregates by scalars. (recursion depth: 1) [-Rscalarrepl]
public override double Render()
^~~~~~
Fractal.cs:127:13: pass remark: inlined direct call to 'complex'. [-Rinline]
complex seed = new complex(Real, Imaginary);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Fractal.cs:136:21: pass remark: inlined direct call to 'complex'. [-Rinline]
complex accum = new complex(m, n);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Fractal.cs:142:29: pass remark: inlined direct call to 'sqabs'. [-Rinline]
if (accum.sqabs() > limit)
^~~~~~~~~~~~~
Fractal.cs:145:33: pass remark: inlined direct call to '+'. [-Rinline]
accum = accum.square() + seed;
^~~~~~~~~~~~~~~~~~~~~
Fractal.cs:121:32: pass remark: replaced 3 aggregates by scalars. [-Rscalarrepl]
public override double Render()
^~~~~~
Fractal.cs:145:33: pass remark: recursively inlined direct call to 'square'. (recursion depth: 1) [-Rinline]
accum = accum.square() + seed;
^~~~~~~~~~~~~~
Fractal.cs:121:32: pass remark: replaced 3 aggregates by scalars. (recursion depth: 1) [-Rscalarrepl]
public override double Render()
^~~~~~
Fractal.cs:121:32: pass remark: replaced 2 aggregates by scalars. (recursion depth: 2) [-Rscalarrepl]
public override double Render()
^~~~~~