我打开了编译器优化,我的多线程 C 程序严重内爆,我可以阅读有关此的文章吗?

问题描述 投票:0回答:3

我正在使用 MinGW,它是 Windows 的 gcc。 我的程序涉及多个窗口、两个不同的主线程以及线程池中用于重叠网络 I/O 的多个工作线程。

无需编译器优化即可完美运行。

A) 编译器优化是否必要? 我的程序已经非常快了。 它有可能提供显着的改进吗?

B) 是否有关于如何正确构建多线程程序以便编译器优化发挥作用的文章?

c multithreading optimization mingw
3个回答
5
投票

“积极内爆”有点奇怪(你的程序是裂变炸弹的控制器吗?),但我知道你的程序在没有编译器优化的情况下表现得如预期,并且神秘地通过编译器优化。

这个问题的技术术语是你的程序有错误。

多线程编程本质上是困难的。当线程共享内存时,多线程编程非常困难;这是并发编程的受虐方式(消息传递更容易正确)。你不需要读一两篇文章,你需要读几本书并获得几年的编程经验。

您很不幸,您的程序似乎无需优化即可运行。它可能无法在时间有点不同的不同机器上工作,或者使用不同的编译器,或者在不同的操作系统上工作。所以你最终浪费了时间认为你的程序有效。但事实并非如此。无论您选择什么优化级别,编译器都会将正确的源代码转换为正确的可执行文件。

¹

当然,排除编译器错误。但机会对你来说非常不利。


3
投票
一种优化模式而非另一种优化模式下的所有家庭失败中,99.9% 都是由于严重错误造成的。 多线程竞争等对代码性能非常敏感。 指令重新排序或循环快捷方式可能会将测试通过变成调试噩梦。

我假设服务器运行正常并在负载下在明显不同的地方引爆,因此传统的调试变得毫无用处?

您将不得不依靠记录和更改测试条件来缩小点火点范围。 我的猜测是,这将是一个 Heisenbug,它会随着代码、优化、选项、负载配置文件、缓冲区大小等的更改而发生变异。

不解决问题不是一个好计划,因为它只会以另一种形式出现在明年具有更多核心的盒子上等。即使优化关闭,它仍然在那里,潜伏着,等待攻击的机会。

我希望我能提供一些安慰。

说真的——用一个好的记录器记录你能记录的一切——一个对日志进行排队的记录器,以便将磁盘延迟排除在主应用程序之外。 改变周围的事物,尝试使错误发生变异,并且可能也会出现在非优化的构建中。 写下(输入)您所做的一切以及任何改变后发生的事情,无论是好还是坏。 让错误变得更糟实际上比让它的症状消失更好(不知道确切原因)。 如果可以的话,在各种硬件配置上尝试服务器。

最终你会发现bug!

您有一件事情适合您 - 似乎您可以可靠地重现该问题。 这本身就是一个巨大的优势。

忘了问——除了核爆炸的比喻之外,主要症状是什么? 是否到处都是 AV'ing/segfaulting,或者是否已锁定或活锁?


1
投票
要回答问题的“A”部分,代码的未优化版本仍然存在并发错误,但线程运行的时间安排使得这些错误尚未在测试工作负载中暴露出来。当前版本的未经优化的程序最终会无法使用,因此您需要修复并发错误,然后才能使用该程序进行实际工作。

© www.soinside.com 2019 - 2024. All rights reserved.