欢迎来到Introzo百科
Introzo百科
当前位置:网站首页 > 技术 > VS2019编译缓慢_...Studio 2019,编辑代码时出现滞后

VS2019编译缓慢_...Studio 2019,编辑代码时出现滞后

日期:2023-09-30 04:36

告诉我我的解决方案。 。我在网上找到了它,这是浪费精力。

1。工具-选项-intellitrace-取消勾选启用选项。

2。工具——选项——文本编辑器——C/C++——高级——代码分析——禁用后台代码分析——改为true

3。工具-选项-文本编辑器-所有语言-滚动条-行为-选择第一个

我刚用了第二个(≧m≦) 转载自:https://www.introzo.com/target=https%3A//www.introzo.com/A/l1dyM8Vgde/

有兴趣的朋友可以尝试一下! (?? 3(???c)

在菜单栏中搜索 codelens 并取消选中启用。

?

点击滚动条,设置如下图:

?选择环境并设置如下图:

进入源码管理并关闭git:

这样修改之后,就会变得非常流畅了! !

背景:在定位某些Crash崩溃时,由于缺乏更多信息,可能需要从反汇编的静态代码段中推断出对应的C++代码,并根据寄存器值来分析具体原因。对于Release版本,由于编译器的强制函数内联和生成指令优化,反汇编代码与C++源代码会有很大差异,这使得我们从汇编代码中推演C++变得更加困难。当我们把优化点分析清楚后,我们就能体会到编译器优化的美妙之处。

本文基于ARM64平台上的崩溃拆解分析经验。发现编译器可以自动添加条件判断并启用128位寄存器的NENO指令进行加速,而无需我们编写任何判断。这就是我以前做过的。我对PC平台上从未见过的优化感到惊讶。我忍不住在我仅有的多个平台上做了进一步的分析,写了一段简单的C++代码。同样的代码在Windows下使用VS2019选择X64、X86、MAC。我们的XCode C++ 64位,Android Studio的ARM64,这四个平台都是用Release版本生成的,然后用IDA进行静态分析对比,感受一下编译器的强大。

我只是简单地写了一个测试样本,一个C++字符串,加上测试,全部只有60行。为了简化,没有专门的内存分配器,也没有引入一些迭代器和提取机制。为了简化,也有直接使用strlen()提取长度等,不符合模板泛型编程等,但这些都不影响分析。无论平台如何,都使用相同的代码,重点将分析 TestMyString() 函数和生成,以及差异最大的 TCopy() 函数。

模板

T* TCopy(const T* pStart, const T* pFinish, T* pDst)

{

for (; pStart != pFinish; ++pDst, ++pStart)

{

*pDst = *pStart;

}

返回pDst;

};

模板

结构TString

{

~TString()

{

if (_StartPtr) 删除 _StartPtr;

}

TString(const T* pcStr)

{

分配(pcStr, pcStr + strlen(pcStr));

}

TString& 运算符 = (const TString& rkRight)

{

if (&rkRight != this)

{

分配(rkRight._StartPtr, rkRight._FinishPtr);

}

返回*这个;

}

void 分配(const T* pStart, const T* pFinish)

{

if (pStart == pFinish || nullptr == pStart)

{

_FinishPtr = _StartPtr;

返回;

}

int iLen = pFinish - pStart;

int iSelfSize = _FinishPtr - _StartPtr;

if (iSelfSize < iLen)

{

if (_StartPtr) 删除 _StartPtr;

_StartPtr = new char[iLen + 1];

_EndOfStrore = _StartPtr + iLen;

}

_FinishPtr = TCopy(pStart, pFinish, _StartPtr);

*((char*)_FinishPtr) = '0';

}

T* _StartPtr = nullptr;

T* _FinishPtr = nullptr;

T* _EndOfStrore = nullptr;

};

使用 MyString = TString;

void TestMyString()

{

MyString s1("HelloWrold");

MyString s2("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");

s1 = s2;

}

windows X64 平台:

我们首先使用VS2019在main函数中调用TestMyString(),然后生成windows的X64平台可执行文件。选择发布。 VS默认以最快的优化。使用IDA反编译工具打开生成的exe,跳转到主代码。部分。好家伙,TestMyString() 消失了。内联扩展直接优化,消除了call和ret的开销,TestMyString中的所有子函数调用也都进行了优化,比如

TString& 运算符 = (const TString& rkRight);

void 分配(const T* pStart, const T* pFinish);

T* TCopy(const T* pStart, const T* pFinish, T* pDst);

变为内联并全部放入 main 中。这也是最常见的优化。

我们重点分析一下:整个汇编代码比较长,我们选取​​部分,也是优化有差异的部分,对这句话s1 = s2;进行反汇编;在C++中。这里应该调用TString的赋值构造函数,但是都是经过优化后放在一起的。为了更好地理解程序集,我对每一行进行了注释解析。您只需要逐行阅读注释即可。如果想更深入的话,可以一边阅读C++代码和注释,一边体验对应,感受编译器的优化。

.文字:

X64总结:非常强的调用优化,除了new和delete系统函数外,减少了所有子函数的调用和ret开销,包括内联TCopy(const T* pStart, const T* pFinish, T* pDst )代码区块,三个参数中省略了pFinish(rbx已经用很久了),也没有脚本。还可以知道T是一个POD类型,没有单独的赋值结构,这也是比较巧妙的。

windows X86平台:

操作与不省略跳转相同。我仔细对比了VS项目的C++优化选项卡,发现win64的omit-frame-pointer为空,所有参数都没有标注“/Oy-”或“Oy”; x86默认为“no”,所以我可以手动打开它。不然会比x64还差。

启用omit-frame-pointe并重新编译生成。用IDA打开,首先发现虽然大部分x86代码直接优化成了main,但是有些函数调用还是没有优化,比如TString::Assign(char const *,char const *),会生成有有很多指令。另外,写法很接近C++,几乎是一行一行的,而且很容易反汇编。

由于篇幅限制,而且它与 ,char const *) 部分非常相似。

.文字:

X86总结:通话优化还不错。除了new和delete系统函数外,就只有TString::Assign(char const *,char const *)。函数的 call 和 ret 开销特定于 x64 指令。相比之下,优化明显不如x64,太像C++逐行翻译了,而且引入了更多的堆栈平衡,而且key复制也不够简洁。

MAC平台:

MAC平台使用XCode生成64位Release可执行程序。项目全部默认值,没有启用单独的优化。发现和X86是同一水平,但是函数调用开销并没有节省多少。调用还是调用,多了堆栈保护和平衡。比x86还要弱。虽然是64位,但是根本没有X64那么激进。

由于MAC下生成的可执行程序反汇编与x86代码类似,且注释重复,所以我们就不逐行分析了。如果有兴趣可以阅读IDA。不过这里我发现了一个亮点,就是MAC启用了SSE指令集,并且使用了XMM的128位寄存器,也就是SIMD,所以还是可以的。摘录此代码并注释它来自 TestMyString() 函数。

__文字:

总结:函数调用比X86保守,没有太多亮点,但实际上是手动使用了SSE指令集。 128位的XMM0除了手动打开之外,直接清除两个指针、SIMD操作等选项。优化期间的亮点。

Android ARM64 平台:

使用Android Studio,选择Native C++项目,将之前的C++代码放入cpp中,选择Release版本,Arm64平台,编译生成.so运行时二进制代码。为此,我专门使用IDA来动态调试一个Release APK。两个字,就是舒服。不过我对IDA和Android开发也是新手,不是很熟悉,所以对它的优化感到惊讶,但后面可能就麻木了。

我这里做了静态分析。总体来说,看起来通话优化很强。除了新建和删除系统函数外,所有子函数都进行了缩减和优化,以减少调用开销。它们也被放在一个头上以增加后退。 C++难度和X64差不多,但是细节没有x64快。

这里说一个非常强的优化,就是启用NENO指令。由于前面三个平台的分析比较多,所以对于特别常见的部分我们就不多赘述了。我们来分析一些汇编代码。实际的 T* TCopy(const T* pStart, const T* pFinish, T* pDst) 代码,这个优化在复制大字符串的时候确实很好,尤其是在真机上调试发布的时候,很精彩。我还使用Android Studio生成了Deubg版本并在真机上进行了调试。我发现没有NENO优化。

NEON技术加速多媒体和信号处理算法(例如视频编码/解码、2D/3D图形、游戏、音频和语音处理、图像处理技术、电话和声音合成),性能至少是ARMv5的3倍, ARMv6 SIMD 性能的 2 倍。本文使用 128 位 Q0 和 Q1。由于前面三个平台的分析比较多,所以对于特别常见的部分我们就不多赘述了。我们来分析一些汇编代码。

.文字:

总结:和

几乎一样的优化级别

概述:在这个简单的测试C++示例中,ARM64编译性能是最强的,优化综合也是最强的。启用NENO指令,自动添加条件语句,一次处理32个字符,完全逊色。如果没有NENO指令,Windows下的X64可以说是最漂亮最强大的优化了。 MAC的其余部分和X86类似,但MAC仍然使用了一点SSE和SIMD,并且至少以128bit运行,这是一个相当大的亮点。两者基本都是按照C++逐行翻译的,中规中矩。

注:本文为原创。如有不足之处欢迎批评指正。编译器优化和开发软件也与目标平台相关。对于相同的代码,不同版本的开发软件生成的代码是不同的。对于相同的平台、相同的软件,编译选项也有很大的关系。本文使用Release版本的默认设置。除了默认的 X86 默认值之外,还可以手动启用 omit-frame-pointer。这里并不是说哪个编译器更好或更差,而是从汇编层面比较不同平台上C++生成的二进制代码的美感。

0条大师的评论

关灯