sjlj vs dwarf vs seh 有啥区别?
Posted
技术标签:
【中文标题】sjlj vs dwarf vs seh 有啥区别?【英文标题】:What is difference between sjlj vs dwarf vs seh?sjlj vs dwarf vs seh 有什么区别? 【发布时间】:2013-03-18 04:51:10 【问题描述】:我找不到足够的信息来决定我应该使用哪个编译器来编译我的项目。在不同的计算机上有几个程序模拟一个过程。在 Linux 上,我使用的是 GCC。一切都很棒。我可以优化代码,它编译速度快并且使用的内存不多。
我用 MSVC 和 GCC 编译器做我自己的基准测试。后来的一个产生稍微快一点的二进制文件(对于每个子架构)。虽然编译时间远远超过 MSVC。
所以我决定使用 MinGW。但是在MinGW中找不到关于异常处理方法及其实现的任何解释。我可以为不同的操作系统和架构使用不同的发行版。
注意事项:
编译时间和内存对我的使用并不重要。唯一重要的是运行时优化。我需要我的程序足够快。慢速编译器是可以接受的。 操作系统:Microsoft Windows XP / 7 / 8 / Linux 架构:Intel Core i7 / Core2 / 和运行 XP 的非常旧的 i686:P【问题讨论】:
我很惊讶 gcc 生成的代码比 MSVC 更快;在过去的几年里,事情一定发生了变化…… @***foe 我被多次告知要使用 MSVC 而不是 MinGW。每个人都认为 msvc 更快!我用一个简单的 cpu-burst 程序测试了 MinGW 7.2 和 MSVC 2010。在带有-O3 -mtune=corei7
GCC 的 corei7 上比 MSVC 快 45%
根据我自己的经验,使用国际象棋移动生成器(使用位板),MSVC 和 Intel C++ 都比 gcc 快 10%,但那是 2 年前...
@Wolf 在那个时候,45% 的速度对我来说意味着执行时间减少了 45%。如果我没记错的话,我们的分子几何建模软件的执行时间是 134s (gcc) 和 194s (msvc) 用于特定测试。尽管如此,现在我认为我的测量方法不正确且不充分(:
@sorush-r 我明白了,你计算出的 (194-134)/134 接近 45%,谢谢。
【参考方案1】:
MinGW-w64 Wiki 有一个简短的概述:
为什么 mingw-w64 gcc 不支持 Dwarf-2 异常处理?
Windows 的 Dwarf-2 EH 实现根本不是为了 在 64 位 Windows 应用程序下工作。在win32模式下,异常 展开处理程序不能通过非 dw2 感知代码传播,这意味着 任何通过任何非 dw2 感知的“外部框架”的异常 代码将失败,包括 Windows 系统 DLL 和使用构建的 DLL 视觉工作室。 gcc 中的 Dwarf-2 展开代码检查 x86 展开组装,没有其他 dwarf-2 就无法进行 放松信息。
SetJump LongJump 异常处理方法适用于大多数情况 win32 和 win64 上的情况,一般保护故障除外。 gcc 中的结构化异常处理支持正在开发中 克服了dw2和sjlj的弱点。在 win64 上, 展开信息被放置在 xdata-section 并且有 .pdata (函数描述符表)而不是堆栈。对于win32,链 的处理程序在堆栈上,需要由 real 保存/恢复 执行代码。
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。 [...]
另见:
Exception handling models of GCC C++ Exception Handling for IA-64 EH newbies howto【讨论】:
感谢您的链接。我打算将 DW2 用于 32 位,将 SEH 用于 64。SEH 在 mingwbuilds (4.8) 中可用。我应该等待 4.8 的稳定版本还是可以?它在这里编译。我目前正在使用 4.8 和 SEH 对我的项目进行依赖。还没有问题... 所有依赖项(包括 Boost 库、OpenSSL、ICU、freeGLUT)都已编译,但 Qt 最终会出现大量内部编译器错误。我想我会等待 4.8 的稳定版本 你是用qt的二进制还是自己编译的? @woreos 我使用自己的 Qt 版本。我发现 Qt 和 GCC 4.8 都没有问题。那是我烧了一半的内存! 1 现在一切正常【参考方案2】:SJLJ (setjmp/longjmp): – 可用于 32 位和 64 位 – 不是“零成本”:即使没有抛出异常,它也会引发次要 性能损失(在异常繁重的代码中约为 15%)——允许异常 遍历例如窗口回调
DWARF (DW2, dwarf-2) – 仅适用于 32 位 – 无永久运行时开销 – 需要整个调用堆栈启用 dwarf,这 意味着异常不能被抛出,例如Windows 系统 DLL。
SEH(零开销异常)- 可用于 64 位 GCC 4.8。
来源:https://wiki.qt.io/MinGW-64-bit
【讨论】:
抱歉,添加了源链接。 所以现在在 2016 年,我们可以把这个问题搁置一旁,简单地始终使用 SEH。 @RustyX 仅当您的目标是 x86_64 时 对于 x86 来说太矮了吗?以上是关于sjlj vs dwarf vs seh 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
restkit vs afnetworking vs mknetworkkit vs nsurlconnection有啥区别[关闭]
有啥区别:ConcurrentUpdateSolrServer vs HttpSolrServer vs CommonsHttpSolrServer?