Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
666 views
in Technique[技术] by (71.8m points)

c# - Array Bounds Check Elimination in the CLR?

I was recently reading this article by Dave Detlefs in which he presents a few cases where the CLR performs array bounds check elimination. I decided to test this myself, so I did the following:

  • Opened Visual Studio 2010 Ultimate SP1
  • Created a new C# project of type Console Application (targeting .NET 4 Client Profile by default)
  • Added the following code (all sub-methods are taken directly from the article):

    class Program {
        static void Main(string[] args) {
            int[] array = new int[30];
            Test_SimpleAscend(array);
            Test_SimpleRedundant(array, 3);
    
            foreach (int i in array) {
                Console.WriteLine(i);
            }
        }
    
        static void Test_SimpleAscend(int[] a) {
            for (int i = 0; i < a.Length; i++)
                a[i] = i;
        }
    
        static void Test_SimpleRedundant(int[] a, int i) {
            int k = a[i];
            k = k + a[i];
        }
    }
    
  • Switched to Release mode; verified that "Optimize Code" is checked in the Build options

  • Added a breakpoint to each array access, started debugging (F5) and opened the Dissassembly window

So here's the dissassembly for a[i] = i; in Test_SimpleAscend:

                a[i] = i;
00000024  mov         eax,dword ptr [ebp-4] 
00000027  mov         edx,dword ptr [ebp-8] 
0000002a  cmp         eax,dword ptr [edx+4] 
0000002d  jb          00000034 
0000002f  call        64FD6E08 
00000034  mov         ecx,dword ptr [ebp-4] 
00000037  mov         dword ptr [edx+eax*4+8],ecx 

The cmp/jb/call is bounds checking, actually forcing the call to be executed throws an IndexOutOfRangeException.

Same thing for all array accesses, including the redundant access in Test_SimpleRedundant. So is there something wrong with my testing methodology, or the CLR doesn't actually eliminate bounds checking? I hope I'm wrong and if so I'd like to know how I can really get array bounds checking elimination.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Thanks to a comment by Cody Gray, I've managed to answer my own question:

By default, JIT Optimizations are disabled when debugging. To fix this, one can go to Debug -> Options and Settings -> Debugging -> General, and uncheck both "Enable Just My Code" and "Suppress JIT Optimization on module load".

Also see https://docs.microsoft.com/en-us/visualstudio/debugger/jit-optimization-and-debugging

With optimization enabled, the bounds check are removed as advertised.

I'll leave this here for documentation purposes.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...