2

I have recently noticed some odd behavior in the CLR optimizer. In particular, certain simple methods were getting optimized out in release builds sometimes. I can run the same program (no user/external input) 10 times in a row and 3 times it will inline one of the methods and 7 times it won't.

So, my question is, does the CLR have optimizations that it applies based on external variables such as current CPU/memory load or DateTime.Now.TotalMilliseconds % 3? Now that I know about the "sometimes" optimizations I can work around it as necessary, but I am curious why I might see different behavior on successive runs of the same program.

Micah Zoltu
  • 6,764
  • 5
  • 44
  • 72
  • 2
    Sounds like your tests have already showed that it's *not* deterministic, so you already have your answer, do you not? – Servy Oct 31 '14 at 16:44
  • Out of curiosity, was there any pattern to the occasions it was inlined? (The first 3, the last 3, some consecutive set of 3, ...) Is the assembly you are testing signed? (Would that have an effect?) – dodald Oct 31 '14 at 17:00
  • It definitely appears to be non-deterministic. I was curious what sort of external factors would affect the outcome. While unlikely, it could just be `Random()` or something. – Micah Zoltu Oct 31 '14 at 17:06
  • I was unable to detect a pattern. It wasn't always the first one I know, and it didn't seem to be patterned or batched in any way. I Didn't spend a lot of time looking for patterns though. Reproducing consisted of hitting up-enter on the command line and inspecting results, so each was run in the same "environment" though temporally separated and with varying amounts of background load on the system. – Micah Zoltu Oct 31 '14 at 17:08
  • 2
    How are you determining whether the method was inlined? – dodald Oct 31 '14 at 17:10
  • 1
    I have never seen or heard of *any* evidence that the jitter pays attention to elapsed time. The jitters included with sscli20 certainly do not. Even if current ones do, knowing the answer is kinda pointless of course since there isn't anything you can do about it. – Hans Passant Oct 31 '14 at 17:29
  • I had a profiler attached that writes to a log whenever a particular method is JIT compiled. The JIT compiler will do inlining optimizations before JIT compilation so the profiler will never see methods that get inlined. I verified this by attaching the NoInlining attribute on the method and the behavior changed such that the profiler now saw the method JIT compiled on every run (instead of 7/10). Also, if the method becomes ineligible for inlining (e.g., add a try/catch to it) then the method is seen by the profiler on every run. – Micah Zoltu Oct 31 '14 at 19:08
  • My question was primarily out of curiosity, not functionality. Personally, I haven't been able to come up with any scenarios where changing optimizations based on external factors (such as overall system performance/usage) would make sense so I was hoping that Stack Overflow could help alleviate my curiosity. My current best "realistic" guess is that some optimizations trade memory for speed and vice versa and perhaps depending on how much memory is available to the application the CLR may choose to go with one instead of the other. – Micah Zoltu Oct 31 '14 at 19:11

0 Answers0