用于超线程的最佳gcc优化开关

Olo*_*ell 6 c performance gcc x86-64 hyperthreading

背景

我有一个EP(Embarassingly Parallell)C应用程序在我的笔记本电脑上运行四个线程,其中包含运行在2.67GHz的intel 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
Run Code Online (Sandbox Code Playgroud)

当编译一个#include所有其他模块的模块时也是如此

-O1 -m64 -mthreads -fschedule-insns -march=native -g -Wall -c -fwhole-program
Run Code Online (Sandbox Code Playgroud)

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

有没有人尝试过这个并取得了不错的成绩?

gna*_*729 1

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

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

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

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