如何找出是啥引入了 AVX 标志
Posted
技术标签:
【中文标题】如何找出是啥引入了 AVX 标志【英文标题】:How to find out what introduces AVX flag如何找出是什么引入了 AVX 标志 【发布时间】:2018-10-17 13:37:32 【问题描述】:我有一个用 Visual Studio 编译的相当大的 x64 c++ 程序。我们有两种编译方式——一种是使用 sln 解决方案文件(来自 IDE 或通过 msbuild),另一种是通过 VS 命令提示符中的 Makefile(然后在内部使用 Visual Studio 的 cl.exe 和 link.exe)。
不知何故,我遇到了通过 Makefile 生成可执行文件并启用 /AVX 指令的情况,而我不想这样做,所以我想了解如何摆脱它。
我尝试在没有任何参数的情况下编译和链接它(尤其是没有 /arch:AVX)。我希望我在 sln 和 Makefile 中编译和链接相同的源代码和库。
找出 AVX 来源的简单方法是什么?项目包括几十个 h/cpp 文件,大约 40 个自己的库,10 个 Windows 库。你会怎么做?
【问题讨论】:
查看 .cpp 文件不会给您带来任何不同,因为那里的任何#pragma
都会同样影响 .sln 构建。检查你的makefile,这就是区别所在。
你不想要 AVX 的原因是什么?
grep Makefile(或其他与构建相关的文件)用于 avx(或“本机”ri,如果您在支持 AVX 的 CPU 上构建,则与您的编译器等效)?
@MSalters:我有一个 sln 文件和一个 Makefile,如何检查它们的差异?我检查了 CL 和 LINK 参数的差异,并尝试使用相同的参数,但没有得到相同的结果... bolov:使用 AVX 编译的 Prorgams 无法在具有不支持 AVX 的 CPU Dan M.: 在项目文件中的任何地方都没有 AVX 的迹象
将/arch:SSE2
添加到除MT 1之外的所有标志并检查结果
【参考方案1】:
简单的方法,找到一台没有 AVX 的旧电脑,在调试器中运行您的应用程序,它会因无效指令运行时错误而崩溃,并将陷入调试器。这样,您将立即找出编译到该指令中的代码。
另一种更难的方法是编写一个 C# 控制台应用程序,将已编译的 DLL 或 EXE 反汇编,并搜索 AVX 指令。你需要Gee.External.Capstone
nuget 包来反汇编,PeNet
包来解析成部分。 Also this code to disassemble。 disassembleStreamEx
方法将返回指令流。搜索 X86InstructionGroup.AVX 或 X86InstructionGroup.AVX2 指令,打印地址,然后使用例如WinDBG + PDB 文件将地址转换为源代码位置。
更新:在此之前,请在您的代码库中搜索包含 _mm256_
和 *.asm
文件的文件。如果幸运的话,您将无需做任何其他事情。
【讨论】:
我知道它包含 AVX(因为它崩溃并且我在反汇编代码中看到 avx 指令),我想知道它在编译期间来自哪里(一些 obj 文件或一些标志)所以我可以关闭它。 VS命令行中已经有反汇编工具:“dumpbin /disasm binary >binary.asm” 如果它崩溃了,调试器会告诉你确切的位置。 VS 调试器只会中断执行并向您显示崩溃的确切源位置。 WinDBG 可以离线完成,收集故障转储 docs.microsoft.com/en-us/windows/desktop/wer/… 然后将转储 + 调试符号 + 二进制文件加载到 WinDBG 并运行!analyze -v
您不仅需要反汇编程序,还需要可以以编程方式使用的反汇编程序,以搜索特定类别的指令。在一个巨大的模块的反汇编中很难找到 AVX 指令。如果你不喜欢 capstone,你可以解析反汇编的 .asm 文件来搜索 AVX,但 IMO 更难。
如果二进制文件是在没有调试符号的情况下构建的,我可以从故障转储中获得一些东西吗? (发布二进制文件)当我为调试符号添加 /Z7 并与 /DEBUG /PDB:"program.pdb" 链接构建二进制文件时......它不再崩溃了。
是的,故障转储分析也适用于发布版本。您需要链接器生成的 .pdb 文件,与您正在运行的构建生成的 .pdb 完全相同(重建会使它失效)。以上是关于如何找出是啥引入了 AVX 标志的主要内容,如果未能解决你的问题,请参考以下文章