sjlj vs dwarf vs seh有什么区别?


147

我找不到足够的信息来确定应该使用哪个编译器来编译我的项目。在不同的计算机上有多个程序可以模拟一个过程。在Linux上,我正在使用GCC。一切都很棒。我可以优化代码,它可以快速编译并使用不太多的内存。

我使用MSVC和GCC编译器做自己的基准测试。稍后的版本会生成稍快的二进制文件(针对每个子体系结构)。尽管编译时间比MSVC多得多。

因此,我决定使用MinGW。但是找不到有关MinGW中异常处理方法及其实现的任何解释。我可以对不同的操作系统和体系结构使用不同的发行版。

注意事项:

  • 编译时间和内存对于我的用法并不重要。唯一重要的是运行时优化。我需要我的程序足够快。慢速编译器是可以接受的。
  • 操作系统:Microsoft Windows XP / 7/8 / Linux
  • 架构:Intel Core i7 / Core2 /和运行XP的非常老的i686:P

5
我很惊讶gcc产生的代码比MSVC更快;在过去的几年中,情况肯定已经发生了变化……
trojanfoe13年

19
@trojanfoe我被告知很多次使用MSVC代替MinGW。大家都认为msvc更快!我使用简单的cpu-burst程序测试了MinGW 7.2和MSVC 2010。在带有-O3 -mtune=corei7GCC的corei7上比MSVC快45%
sorush-r

5
以我自己的经验,使用棋盘移动生成器(使用位板),MSVC和Intel C ++都比gcc快10%,但这是2年前的事
trojanfoe13年

2
@Wolf在那段时间里,速度提高45%意味着对我来说执行时间减少了45%。如果我没记错的话,对于一个特定的测试,我们的分子几何建模软件的执行时间是134s(gcc)和194s(msvc)。不过,现在我认为我的测量方法不正确且不足(:
sorush-r

2
@ sorush-r我看到,您计算出(194-134)/ 134,接近45%,谢谢。

Answers:


109

MinGW-w64 Wiki上有一个简短的概述:

mingw-w64 gcc为什么不支持Dwarf-2异常处理?

Windows 的Dwarf-2 EH实现根本不适合在64位Windows应用程序下工作。在win32模式下,异常展开处理程序无法通过不了解Dw2的代码传播,这意味着通过任何不了解Dw2的“外来框架”代码进行的任何异常都将失败,包括Windows系统DLL和Visual Studio内置的DLL。gcc中的Dwarf-2展开代码检查x86展开组件,如果没有其他dwarf-2展开信息,将无法继续进行。

SetJump跳远踏板异常处理工程对Win32和Win64中大多数情况下的方法,除了一般保护错误。为了克服dw2和sjlj的弱点,正在开发gcc中的结构化异常处理支持。在win64上,展开信息位于xdata-section中,并且存在.pdata(函数描述符表)而不是堆栈。对于Win32,处理程序链位于堆栈上,需要通过实际执行的代码进行保存/还原。

GCC GNU关于异常处理

GCC支持两种用于异常处理(EH)的方法:

  • DWARF-2(DW2)EH,它要求使用DWARF-2(或DWARF-3)调试信息。DW-2 EH可能导致可执行文件稍微膨胀,因为大型调用堆栈展开表必须包含在可执行文件中。
  • 一种基于setjmp / longjmp(SJLJ)的方法。基于SJLJ的EH比DW2 EH慢得多(在没有抛出异常的情况下,即使正常执行也会受到惩罚),但可以跨未使用GCC编译的代码或没有调用堆栈展开信息的代码使用。

[...]

结构化异常处理(SEH)

Windows使用自己的异常处理机制,称为结构化异常处理(SEH)。[...] 不幸的是,GCC尚不支持SEH。[...]

也可以看看:


7
感谢您的链接。我将对32位使用DW2,对64位使用SEH。mingwbuilds(4.8)中提供SEH。我应该等待4.8的稳定版本还是可以的?它在这里编译。我目前正在使用4.8和SEH来依赖我的项目。尚无任何问题……
sorush-r

2
所有依赖项(包括Boost库,OpenSSL,ICU,freeGLUT)都已编译,但Qt最终会出现许多内部编译器错误。我想我会等待4.8的稳定发布
sorush-r

您使用qt的二进制文件还是自己编译?

4
@woreos我使用自己的Qt构建。我发现Qt和GCC 4.8都没有问题。那是我半烧完的RAM!1现在一切正常
sorush-r

82

SJLJ(setjmp / longjmp):–可用于32位和64位–非“零成本”:即使未引发异常,也会导致较小的性能损失(在异常重代码中约为15%)–允许异常遍历例如Windows回调

DWARF(DW2,dwarf-2)–仅适用于32位–无永久运行时开销–需要整个调用堆栈都启用dwarf,这意味着无法抛出异常,例如Windows系统DLL。

SEH(零开销例外)–适用于64位GCC 4.8。

来源:http : //qt-project.org/wiki/MinGW-64-bit


2
抱歉,已添加源链接。

2
感谢您的回答;)
sorush-r

14
因此,现在在2016年,我们可以解决这个问题,而始终使用SEH。
rustyx

6
@RustyX仅当您的目标是x86_64时
sohnryang

那么x86的矮人呢?
banguru
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.