3

I am a little bit disappointed in the CLR's optimizer. Suppose I have the following piece of code:

int i = 0;
for (int j = 0; j < 10; ++j)
  ++i;
Console.WriteLine("{0}", i);

It's clear that at the end of the loop the local variable 'i' should have the value 10. Modern C++ compilers would optimize this piece of code to a simple:

Console.WriteLine("{0}", 10);

To my surprise, the CLR JIT-compiler doesn't seem to be that smart. When I compile the piece of code above, then it iterates 10 times instead of assigning the value directly. Multithreading is no issue here, because all data access is on the stack and therefor thread-specific.

Can somebody point out how smart the CLR optimizer is? I don't see the use for the volatile keyword, when the compiler doesn't optimize access to variables/fields.

Ramon de Klein
  • 5,172
  • 2
  • 41
  • 64
  • From my point of view - this is right behaviour of a compiler. I'm not sure whether a compiler should execute a code in order to see which final value of a variable would be and then replace it by a manually calculated one – sll Dec 15 '11 at 16:04
  • 1
    @sll: Why not? That's perfectly valid constant folding. –  Dec 15 '11 at 16:05
  • 3
    I don't see how this is on-topic for this site. You're not asking how to do something, or for advice, you're using it as a forum to point out what you see as a flaw in the optimizer. The proper forum for this would be a Microsoft site or something you could submit as a bug. – David Dec 15 '11 at 16:05
  • @delnan : really I do not know, this is my feeling and I assume this could be wrong feeling since I'm not a compiler optimization expert – sll Dec 15 '11 at 16:07
  • 2
    The jitter optimizer doesn't eliminate for loops that have no side effect. This is intentional, the assumption is that they *do* have a side-effect. Take time. It doesn't otherwise have enough cycles available to do the kind of analysis needed to optimize the given snippet, it needs to work with the constraints of "just". An overview of optimizations it performs is here: http://stackoverflow.com/questions/4043821/performance-differences-between-debug-and-release-builds/4045073#4045073 – Hans Passant Dec 15 '11 at 16:12
  • The C++ compiler from MSVC 2010 can optimize away a loop to 100 million with simple arithmetic in it (like x += 2) and compute the final answer. I was quite amazed by this – Meh Dec 15 '11 at 16:41
  • @Adal well how much time do you usually spend compiling C++ solutions compared to C# ones? – oleksii Dec 15 '11 at 18:16
  • I have a special interest in compiler optimization and I was quite amazed that the modern CLR seems to have such a lousy optimizer. But maybe it doesn't optimize when running in the debugger (even when it is run in release mode with optimization). This would be bad, because you want to be able to debug the real execution flow. A good optimizer can help to speed up execution a lot. I think you should program as efficient as possible, but sometimes optimizers can do more than you can (without sacrificing readability and maintainability). – Ramon de Klein Dec 15 '11 at 20:31
  • @David Stratton: I asked this question to know when I should use volatile (in multi-threaded code). Suppose I check a variable inside a loop that is altered by another thread. In C++, I need to use volatile, because the optimizer might think that this variable isn't modified. In existing C# code I see the same trick, but without using volatile and this code works fine in release builds. I started investigating and I found out that the CLR optimizer isn't optimizing as aggressive as C++ optimizers. I agree that the title is more a statement instead of question. I should rephrase the subject. – Ramon de Klein Dec 15 '11 at 20:38

0 Answers0