设为首页 加入收藏

TOP

CPU工作方式、多核心、超线程技术详解[转贴](三)
2019-08-23 00:32:12 】 浏览:420
Tags:CPU 工作 方式 核心 线程 技术 详解 转贴
、4个队列的、4个大厨的食堂,每个队列有几个客人? - 16个。

哪个快?应该是第一个,因为同时8个服务生,交错开接单,当然能减少某个客人犹豫、磨磨叽叽带来的延迟。让4个大厨忙个不停。

 

别忘了,我们之前已经探讨了,开启超线程以后,因为增加了4个服务员,会带来额外的开销 - 每个客人入队前都会犹豫,都要花时间思考 - “两个队我究竟应该怎么排?哪个队人少?哪个服务生看的养眼?。。。。”。这种额外的开销(处理延迟,性能损耗)是硬件级别的,是英特尔设计CPU的时候就规定死了的。我们任何事都无法解决硬件方面的问题。而唯一的办法就只能是 ---->  关掉HT。但关掉HT,每个队列变成16个客人,而每个服务生,从接待8个客人,增加到16个客人(AS延迟从8份,增加到了16份),怎么破????

 

重头戏来了,硬件我们当然无法改动,但是软件程序上我们可以进行优化,我们可以重写程序的并行调度算法,使得程序最大程度上针对CPU天生的硬件架构进行优化。具体的算法上细节太专业不容易懂,我举下面这个例子一说,你可能明白了:

 

例子:

比如来了64个客人,每个人都想吃一个盖浇饭。来到一个4个服务生、4个队列的、4个大厨的食堂。每个队列会有几个客人? - 16个。

 

好,对于每一个队,现在我不让这16个人都去排队,而是从队里面推选出1名代表,让这个代表代替16个人去向服务生点单。一个单子上16份盖浇饭,其余15人退后。这样一来,总共只有4个客人(代表)点单,其余的60个人在下面歇息。而点单速度方面,每个队最多也就(一个代表)磨叽一次。后堂大厨接到16份盖浇饭的订单,也只有拼命做的份。你总不能炒一个盖浇饭歇5分钟吧。。。

 

瞧, 是不是问题解决了?

1)既避免了8个服务员、开8个队列所带来的AS额外开销

2)也最大程度的利用了大厨(减少了PU的闲置时间)

 

作为一个超算系统,大家都在追求极限性能。世界上每年都会进行500强超级计算机性能排名,一点点的性能差异都有可能会让你的排名退后不少,所以大家都需要尽可能地压榨系统的最后一点性能。

 

同时,这个实例也告诉DIY玩家们,硬件重要,软件也重要。硬件强悍的同时,软件(驱动)也要进行相关的优化。如果软件没有针对性的优化,再强的硬件也发挥不出100%的威力。这个也从侧面解释了为什么有些硬件,属于跑分王类型。比如测试3Dmark这种,得分暴高,而一到实际游戏中,表现一塌糊涂。

 

买硬件,要买用的人多的,不要搞太小众的东西。

 

软硬兼施,不仅硬件性能要强,软件优化也要做到位 

 

1)相对于4核8线程(开超线程),4核4线程(关超线程)后在处理(调度)多线程方面的劣势,我们完全可以通过修改源代码,把这个劣势给抵消掉。而8线程(多了4个硬件AS)所带来的硬件架构方面的额外开销,这个可以理解成集成电路级别的,我们无能为力。

 

所以就像华山的剑宗和气宗。

剑宗就是:简单的增加程序线程的数量,同时打开CPU超线程功能。

气宗就是:修改程序,做算法上面的改变,手动的计算运算周期,调整并行策略,将延迟隐藏掉。

剑宗速成,气宗慢成。同样练1年,剑宗练到6级威力,而气宗只能是3级。但是如果给足够时间,剑宗的极限只能练成9级,就无法突破了。而气宗最终可以练到10级。

 

2)还有就是优化。这里面牵涉到一个平衡的问题。性能 vs 通用性。

 

举个简单例子,如果给你一个加法运算:

1+1+1+1+1+1+1+1 (8个1相加,当然现实中,这么小颗粒度的运算根本没有必要进行并行,不值得。这里是为了举例需要。)

 

第一种方案 (性能低下+通用性最高):

什么优化都不做,程序员只要小学一年级毕业就行了。程序太简单明了了,一行搞定,扔给CPU,做了7次运算,算一次1秒钟,这样就是7秒钟。多核一点用都没有,完全是拼单核性能。强调一句:一个单序程序(serial program)比如8个1相加,你不在代码级别做并行化,它不会自己变成一个多核程序。也就是说:它只会用一个核!!!这里,没有奇迹,没有魔术!怎么做并行化?改你的程序,用上pthread, fork, MPI, openMP。。。等很多种方法,具体细节不多说了。感兴趣的话求助一下度娘。

 

总时间:7秒钟

  

第二种方案 (良好性能+高通用性)

做并行优化:

1)首先,数一下你的机器有几个核,这里假设只有物理核。好,数好了,有4个核,花费0.5秒钟 (时间值只是举例)。

2)这时,我可以根据核的数量(=4),把运算劈成4份,产生4个(程序上的)线程,变成下面形式,从而和硬件核心个数(=4)进行1:1匹配。这样的调度开销0.5秒钟,

3)然后,开始下面的计算

(1+1) (1+1) (1+1) (1+1)第一轮每个核都是一次运算,共1秒钟

(2+2) (2+2)                             第二轮1号2号核都是一次运算,共1秒钟

(4+4)                                           第三轮只有1号核工作   共1秒钟

 花了1+1+1=3秒。而且这个也是有数学证明的(Divide and Conquer问题,具体细节不多说了。感兴趣的话求助一下度娘), 相信大家都学过对数,Log28 = 3 。                      

        

总时间:0.5+0.5+3=4秒钟

   

第三种方案,比较极端 (极限性能+低通用性)

如果,我知道我的系统里面有4个核,是不是:1)数多少个核 2)调度开销 全都可以省了?好,这些费时间的步骤全部去掉。直接奔步骤3)。

---->  这样,最终只要3秒钟。

但是,这种方法只适合4核的机器,如果你给他双核或者8核的机器,整体速度会大打折扣,还不如第二种方案,因为第二种方案带有一定的通用性和自适应性。而第三种方案是“死”的,无脑的。也就是编程时候的hard coding (翻译过来叫死码或硬码),这种编程习惯不推荐,因为写出来的程序实用性会很差。

 

现在不知道你看出点端倪来了没有?

 

其实,我们系统测试追求的是第三种方案,因为我们非常清楚自己系统的架构。完全不用考虑什么比如双核和4核CPU的情况(我们一般多用8核的U)。CPU中二级三级缓存的大小都是固定的。也就是说我们的代码优化可以是非常极端的,完全面向特定型号硬件的优化。这样的优化换来的就是低通用性,也就

首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Delphi 7~XE系列升级安装Indy10.6 下一篇没事做的Delphi版的俄罗斯方块游..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目