0

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

没有编译器优化,它工作得很好。

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

B)是否有关于如何正确构建多线程程序以便编译器优化可以完成其工作的文章?

4

3 回答 3

5

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

技术术语是您的程序有错误。

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

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

¹当然,排除编译器错误。但对你不利的可能性非常大。

于 2012-04-18T22:15:23.757 回答
3

在一种优化模式下,99.9% 的家庭故障都是由于严重的错误造成的。多线程竞赛等对代码性能非常敏感。指令重新排序或循环快捷方式可以将测试通过变成调试的噩梦。

我假设服务器运行正常并在明显不同的地方在负载下引爆,所以让常规调试没用?

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

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

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

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

最终,您会发现错误!

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

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

于 2012-04-18T22:24:28.627 回答
1

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

于 2012-04-18T23:42:55.280 回答