看上去很美--超线程

原文:http://www.agner.org/optimize/blog/read.php?i=6


现在的大端(字节序)微处理器拥有双核或者更多核已经不是一个新闻了。 多线程应用利用多核的的优势,能同时运行多个线程。 如果你在一个四核的处理器上运行一个四线程的程序,你的程序很可能获得四倍的性能。有些处理器则通过在一个核上同时运行多个线程的方式更进一步的利用多线程的优势。 这就是Inter所谓的“超线程”。 例如: Intel 酷睿I7处理器拥有4个核却能让8个线程同时运行--每两个线程公用一个核。 显而易见的是同一时刻能同时运行的线程越多, 单位时间内你能完成的工作就越多。 但有一个问题,其实运行在同一个核上的两个线程在竞争同样的资源。如果这两个线程都只得到了一半的资源, 那么超线程带来的收益就为0.  两个线程以一半的速度运行带来的收益不会比一个线程全速运行带来的收益多。

为了观测超线程其中一个线程到底能跑多快,我曾对超线程做个一些实验。 以下是超线程之间共享的资源列表:
1. 缓存
2. 代码分支预测资源
3. 指令读入和解码资源
4. 运行单元
如果以上任意资源成为了线程运行速度的限制因素, 那么超线程将毫无优势, 反正则超线程大有用武之地。 具体而言, 在如下的情况下超线程是很好的选择。
1. 内存数据过于分散, 以至于不管线程是使用全部cache还是一般的cache, cache命中率都很低。 这样的话, 超线程能使一个线程在等待没有命中cache的数据调入的同时让另一个线程继续使用运行单元 。
2. 不管线程是使用全部或部分的代码分支预测资源, 都有大量的分支预测错误。 这样的话, 超线程能在一个线程在等待指令读入的过程中让另一个现实使用运行单元。
3. 代码中有大量长依赖链(long dependency chains 是啥?)阻止了执行单元的高效利用。

在以上情况下, 超线程将获得小于100%的收益。 超线程的不会是性能翻倍, 而只是让性能有所增长, 比如25%。 另一方面, 如果诸如指令读取, 内存读取或者乘法单元,成了程序运行速度的瓶颈, 那么超线程将不会提高性能。实际在, 在最坏的情况下, 由于线程间资源的竞争, 超线程甚至会降低程序的性能。只需要google一下, 你就会找到大量禁止超线程,程序性能不降反升的案例。


我在两种处理器上对超线程进行了测试--Intel 酷睿I7和Intel Atom。 I7拥有四核, 处理器相当强大。每一个核的执行单元都性能强大,以至于很少有一个线程能耗尽其所有潜力。 看上去让一个核同时运行两个线程是个不错的注意。 可惜的是,I7的指令读取单元没那么强大, 即使在单线程情况下也可能成为程序的瓶颈。 打开超线程后, I7能同时跑8个线程, 在特定的用例下, 性能提高显著。 但是,到底有多少程序能使8个线程同时跑满呢?
Intel Atom 相比而言就没那么强大了, 这种处理器一般用在小笔记本和嵌入式环境中。 他只拥有两个核, 最多能让四个线程同时运行。他的执行单元远没有I7那么大,听起来让两个线程共享这个本来就捉襟见肘的执行单元不是一个怪诞的主意。 这个主意的原因是Atom缺少大处理器所拥有的out-of-order capabilities 。 当执行单元在等待不在cache中的数据读入或者其他的长延时事件时,除非有另一个线程可以继续调入工作, 否则执行单元被白白浪费。

关于以上处理器的详尽介绍,请移步我的处理器架构手册www.agner.org/optimize/#manuals.

明显, 让程序员直接去判断超线程对一个特定的程序是否有收益不是一件容易的事情。 判断这个问题得最稳妥的方法是进行测试。 理论上,打开和关闭超线程的对比测试应该在不同的处理器和不同的数据集上分别进行。这对开发者而言确实是一个沉重的负担, 估计没有几个程序要愿意花这么多时间和财力在测试超线程对他的程序的影响上。


如果说超线程并没有看上去那么美好, 这就引发了第二个问题--怎么关闭超线程? 教会用户如何才BIOS启动程序中关闭超线程不是一个明智的选择, 小白用户们可能根本不会, 也不是所有的BIOS都支持设置,而且关掉超线程还可能对该计算机上跑着的其他程序造成不好影响。 程序员需要将“避免超线程”这个功能放到他的程序中去。 首先程序需要判断它运行所在的计算机是否开启了多线程。 最新的Windows版本提供了获取该信息的系统调用(what?),而在linux环境中你就只能去读配置文件了。 如果检测到开启了超线程,那么只将自己的程序绑定到编号是偶数的逻辑核上去,这样能避免线程来竞争同一个物理核上的资源。
不幸的是, 你阻止不了操作系统利用这些空闲的逻辑核来做一些事情。让处理器严格的使一个线程的优先级高于另一个线程是不可能的(why), 有时候操作系统会让两个优先级差别明显的线程跑在同一个处理器上,这时候低优先级的线程会偷走高优先级线程的资源(甚至造成优先级反转)。 这一点即使在最新的WINDOW7系统上我也发现了。不让不同优先级的线程跑在同一个核上是操作系统应该完成的功能(不懂), 可惜操作系统的设计者们目前还没有完全解决这一的问题。

程序员所需要的是一个系统调用, 这个系统调用能告诉操作系统我不想让每一个核上跑超过一个线程并且我也不想和别的任何程序分享我所占用任意一个核。 可是据我所知这样的系统调用迄今为止没有操作系统有提供。


除了Intel外别的处理器厂商也使用超线程。 事实上有传闻AMD将在他们未来的处理器上增加超线程的功能。超线程确实能让处理器跑出更漂亮的测试数据, 这是说服小白用户们选择他们处理器的一大卖点。 但是处理器设计者们也要考虑到没有多少用户能准确的运用超线程。 这个技术将抉择的重担转移到了软件开发者和操作系统设计者身上。我很怀疑如果将处理器上用于实现超线程的硅空间用于实现别的功能,是不是反而会使一个更好的选择?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值