微软大幅改进Visual Studio调试构建性能

微软调整Visual Studio x86/x64 C 编译器的默认调试配置,使得执行性能大幅提升,在Visual Studio 2019 16.10 Preview 2版本中,微软通过消除不必要的执行时检查(Runtime Checks,/RTCs)的开销,将调试模式编译程序的速度提高到2到3倍。

Visual Studio在调试模式编译程序代码的时候,会默认将一些旗标传递给C 编译器,像是/RTC1、/JMC和/ZI等,这些旗标各自有其调试功能,但是旗标的交互作用,可能会大幅增加开销,特别是涉及/RTC1的时候。因此微软通过消除不必要的开销,来确保Visual Studio可以在抓出程序代码错误的同时,让调试体验更加顺畅。

微软解释,当/JMC和/ZI旗标和/RTC1整合使用时,Visual Studio会初始化分配的堆栈空间,而这项工作会占用大量CPU周期。但并非所有情况都需要进行初始化,微软证明了在编译时,这些检查工作都是不必要的,并且提到,有许多C 的程序代码库都有类似的功能,而消除检查工作就是提升调试性能的方法。

所有调试性能低落的根源,都源于不必要的初始化工作,而且编译器可以在真正需要堆栈初始化的时候,再进行初始化,对于其他情况,Visual Studio都可以安全地跳过初始化,因为在这个过程的执行时检查,并不会找出有用的东西。

不过,当开发者使用编辑并且继续编译功能,情况就会变得复杂,因为开发者可以在调试对话中,添加未初始化的变量,只有在初始化堆栈区域才能检测到该变量。所以为了解决这个问题,微软在调试信息中加入必要的位元,通过Debug Interface Access SDK公开,通过这个信息告诉调试器/ZI填充区开始和结束的位置,同时也告诉调试器,该函数是否需要堆栈初始化。

如果需要初始化,那调试器就可以在调试对话期间,对函数的内存范围无条件进行初始化,新变量将总是分配在初始化区域的顶端,而执行时检查就会检查新加入的程序代码安全与否。微软对新的调试配置进行实验,发现所有项目的调试性能都提高到2到3倍,使用更多STL的项目,性能可能会有更明显的提升。