c - 超线程的最佳 gcc 优化开关

标签 c performance gcc x86-64 hyperthreading

背景

我有一个 EP(令人尴尬的并行)C 应用程序在我的笔记本电脑上运行四个线程,其中包含一个以 2.67GHz 运行的英特尔 i5 M 480。这个 CPU 有两个超线程内核。

四个线程在不同的数据子集上执行相同的代码。代码和数据可以毫无问题地放入几个缓存行中(完全放入 L1 中并有剩余空间)。该代码不包含除法,基本上受 CPU 限制,使用所有可用的寄存器并进行一些内存访问(在 L1 之外)以在序列完成时写入结果。

编译器是 mingw64 4.8.1,相当新。最好的基本优化级别似乎是 -O1,它导致四个线程的完成速度比两个线程快。 -O2 和更高版本运行速度较慢(两个线程完成速度比四个线程快但比 -O1 慢)与 -Os 一样。每个线程平均每秒执行 337 万个序列,每个线程约有 780 个时钟周期。平均每个序列执行 25.5 个子操作或每 30.6 个周期执行一个子操作。

因此,两个超线程在 30.6 个周期内并行执行的操作,一个线程将在 35-40 或 17.5-20 个周期内按顺序执行。

我在哪里

我认为我需要的是生成的代码不那么密集/高效以至于两个超线程不断地在本地 CPU 资源上发生冲突。

这些开关工作得很好(当逐个模块编译时)

-O1 -m64 -mthreads -g -Wall -c -fschedule-insns

在编译一个#include all others的模块时也是如此

-O1 -m64 -mthreads -fschedule-insns -march=native -g -Wall -c -fwhole-program

两者之间没有明显的性能差异。

问题

有没有人试验过这个并取得了很好的效果?

最佳答案

你说“我认为我需要的是生成的代码,它不是那么密集/高效,以至于两个超线程不断地在本地 CPU 的资源上发生冲突。”。这是相当错误的。

您的 CPU 有一定数量的资源。代码将能够使用一些资源,但通常不是全部。超线程意味着您有两个能够使用资源的线程,因此将使用更高百分比的资源。

您想要的是最大化已使用资源的百分比。高效的代码首先会更有效地使用这些资源,添加超线程只会有所帮助。你不会通过超线程获得那么多的加速,但那是因为你已经在单线程代码中获得了加速,因为它更有效。如果你想吹嘘超线程给你带来了很大的加速,当然,从低效的代码开始。如果你想要最快的速度,从高效的代码开始。

现在,如果您的代码受到延迟的限制,这意味着它可以执行相当多的无用指令而不会受到惩罚。使用超线程,这些无用的指令实际上是有成本的。因此,对于超线程,您希望最大限度地减少指令数量,尤其是那些被延迟隐藏并且在单线程代码中没有可见成本的指令。

关于c - 超线程的最佳 gcc 优化开关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22958489/

相关文章:

linux - 为什么我无法在 ubuntu 上运行基于 alpine 构建的 C 程序?

c - 结构体与链表代码C中动态分配的结构体

c++ - 如何从 C 调用在 MATLAB 中创建并在 C 中编译的函数?

c++ - 如何抑制#成为doxygen中的标记字符

javascript - 在函数内执行 addEventListener()

c++ - 与 C++ 相比,用 Python 编写的 wxWidget 慢多少?

performance - 如何在 vim 中基于增量搜索切换选项卡?

c - Linux 的 GCC 替代方案,支持 OpenMP 和带 +、-、*、/和 % 的 128 位整数

c - GCC 析构函数行为

c - gcc 链接选项 -L : Alternative ways how to specify the path to the dynamic library