CLR 中的数组边界检查消除? [英] Array Bounds Check Elimination in the CLR?

查看:44
本文介绍了CLR 中的数组边界检查消除?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在阅读 这篇文章 由 Dave Detlefs 撰写,他在其中介绍了一些 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:

  • 打开 Visual Studio 2010 Ultimate SP1
  • 创建了一个控制台应用程序类型的新 C# 项目(默认针对 .NET 4 Client Profile)
  • 添加如下代码(所有子方法均直接取自文章):

  • 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

    这里是 a[i] = i 的反汇编;在 Test_SimpleAscend 中:

    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 
    

    cmp/jb/call 是边界检查,实际上强制执行调用会抛出 IndexOutOfRangeException.

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

    所有数组访问都是一样的,包括 Test_SimpleRedundant 中的冗余访问.那么我的测试方法是否有问题,或者 CLR 实际上并没有消除边界检查?我希望我是错的,如果是的话,我想知道我如何才能真正获得数组边界检查消除.

    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.

    推荐答案

    感谢 Cody Gray 的评论,我已经设法回答了我自己的问题:

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

    默认情况下,调试时禁用 JIT 优化.要解决此问题,可以转到调试 -> 选项和设置 -> 调试 -> 常规,然后取消选中仅启用我的代码"和在模块加载时抑制 JIT 优化".

    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".

    另见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.

    这篇关于CLR 中的数组边界检查消除?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆