Bug 33003 - Performance problem when in inlining methods
Summary: Performance problem when in inlining methods
Status: NEW
Alias: None
Product: Runtime
Classification: Mono
Component: JIT ()
Version: 4.0.0
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Bugzilla
Depends on:
Reported: 2015-08-12 09:58 UTC by Moritz Uehling
Modified: 2015-08-13 13:56 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report for Bug 33003 on GitHub or Developer Community if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: GitHub Markdown or Developer Community HTML
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:

Description Moritz Uehling 2015-08-12 09:58:04 UTC
Sample code: https://gist.github.com/moritzuehling/b40921f4eeac744027f6

I have a very short method: 

	public void CalculatePoint(double cr, double ci, ref double zr, ref double zi) {
		var zr_old = zr;
		zr = (zr * zr - zi * zi) + cr;
		zi = 2 * (zi * zr_old) + ci;

I call this in a normal instance-method many times. [MethodImpl(MethodImplOptions.NoInlining)] or AggressiveInlining make no difference in performance, inlining the method manually by copying the source-code speeds up the code significantly. See the gist for more details. 


| Arch | Inlining                | Time taken   | Relative Time |
|  x86 | Aggressive (Attribute)  |    147687387 |          100% |
|  x86 | No Inlining (Attribute) |    146419297 |        99.14% |
|  x86 | Manually Inlined        |     97312791 |        65.89% |

Expected Result:

Automatic inlining should be faster than no inlining, and be close / equal to the performance of the manually inlined code. 

https://github.com/akoeplinger has verified that the method is inlined on his system, and the performance-behavior was similar (https://gitter.im/mono/mono?at=55cb4d178f067d637599112e) on his system. 

> I checked with mono -v -v -v -v test.exe | grep INLINE and the method is indeed inlined, so the root cause may be somewhere else
> INLINE START 0x2680d40 LeckerBrot.Program:Main () -> LeckerBrot.RowCalulator:.ctor ()
> INLINE END LeckerBrot.Program:Main () -> LeckerBrot.RowCalulator:.ctor ()
> INLINE START 0x2680e40 LeckerBrot.RowCalulator:Calc () -> LeckerBrot.RowCalulator:CalculatePoint (double,double,double&,double&)
> INLINE END LeckerBrot.RowCalulator:Calc () -> LeckerBrot.RowCalulator:CalculatePoint (double,double,double&,double&)

System Information: 

Processor: Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz

$ uname -a
Linux moritz-P15SM 3.19.0-15-generic #15-Ubuntu SMP Thu Apr 16 23:32:37 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

$ mono --version
  Mono JIT compiler version 4.0.3 (Stable Tue Aug  4 09:43:57 UTC 2015)
  Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
Comment 1 Zoltan Varga 2015-08-12 23:18:59 UTC
The mono JIT is not smart enough to get rid of the 'ref' modifiers, so even with the method inlined, it will load/store the values many times.
Comment 2 Moritz Uehling 2015-08-13 13:56:25 UTC
I have tried it on the same machine under Visual Studio, with the original VS JIT.

(Windows 10, VS15, Release, .NET 4.5.2, Default Console Project)

Results: (times relative to the time taken on Linux with agressive inlining)

Aggressive: 290886075 - 196.96%
NoInlining: 290073532 - 198.11%
  Manually: 6799670 - 46.04%

So the manually inlined variant is faster, but the rest is slower.