多线程与超线程

记得当初上学的时候,即使是那些对自己专业比较热爱的同学依然对计算机组成原理和体系结构这种课程提不起兴趣来。因为这两门课涉及到了硬件,而我们大部分人毕业后的工作都是软件相关,所以会感觉既枯燥又无用。但现在想想,如果我们毕业后悲催的选择了本行工作,工作很长时间后依然木有涉及到一点内核以及硬件机制的话,我们大可以找个没人的地方集体痛哭一场。。。今天我要跟大家分享的是多线程和超线程的一些知识。

       在讲多线程之前,我先讲一下神马是同步、神马是异步。简单的说,同步就是要两端按照同一个频率来进行消息处理,异步就是两端按自己的频率来进行消息处理。我们略去底层硬件定义的那种晦涩的解释方式,用比较通俗的语言来解释下:

同步:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式;

异步:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。

如果还不够形象的话可以看我下面这个比喻:

同步就好比一个痴情的男子去追心爱的姑娘,这位姑娘被打动了就会接受他的爱;如果这位姑娘不接受,他就会不停的追求,直到姑娘答应了,月老的这次任务才算完成;

异步就好比一个花心的男子不停的去追很多漂亮的姑娘,不同的姑娘反应不同,有的可能立马就答应,也有的可能要等到嫁不出去再答应,花心的男子当然会跟先答应他的姑娘交往,不会在那傻傻的等待。

       所以,好姑娘一般都喜欢同步的男生,异步也就意味着异心,很显然,同步存在等待时间,所以追到好姑娘需要耐心。

       下面我们讲一下多线程。假设现在有一个CPU,运行两个线程,那么这两个线程其实不是并行运行的,在微观的CPU内部里面,还是串行处理的。CPU通过线程中断,让某一个线程挂起来,然后切换到另一个线程,执行一会儿,再切换回来,使得宏观上看上去好像两个线程同时运行一样。线程切换肯定会带来一定的性能牺牲,于是我们可以增加CPU,这样就真正的做到微观上面的线程并行了,然而线程数大于物理CPU核数后肯定会带来线程切换带来的性能影响,那为何要用多线程呢?

       计算机最重要的部位就是CPU,只有当CPU充分利用的时候,计算机的威力才会被发挥回来,因此我们的目的就是提高CPU的利用率,不让其空闲。

        假设我们现在运行的任何程序都是纯异步的,也就是说没有存在任何的等待时间,换一句话说CPU从来不会空闲起来,此时的线程数如果大于物理CPU个数的话将会得不偿失,因为线程切换回带来一定的性能开销。

       然而不幸的是,现实总是那么的残酷,世界到处存在等待的时间,CPU也不例外。想想看买票都需要排队等待呢,换句专业的术语就是“同步”。那我们想想为啥我们现实生活中会发生等待现象呢?因为资源单一,试想一下,如果我们每个人都有票了,那还排啥队啊,为啥买票,票不在我们手里呗;为啥排队,售票点就那么几个,人又那么多,无规矩不成方圆呗。

      计算机里面同样也是这样的情况,就那么几个硬件,比如我就一个硬盘,可是四个CPU来访问,这时候CPU多有啥用,你还是得等待,不等待就跟你买票付了钱,人家突然冲过来把票抢走了,神马素质啊。这就是互斥锁存在的意义了,访问共享资源的时候要锁住线程,不能让其他人来抢劫。别人就只能等待了。

       等待意味着什么,意味着你只能想办法浪费时间了,睡觉也好,打游戏也好,听音乐也好。如果这个线程等待了,就相当于它去睡觉了,那如果此时CPU只有一个线程呢?这个线程等待的时候, CPU就空闲着了。这就是多线程存在的意义了,在大多数存在同步等待情况的程序中,线程数如果大于物理CPU个数的时候,是可以充分利用CPU,提高性能的。但无限制的加大线程数会带来线程切换的开销,所以一个服务程序的最优线程数需要根据具体情况来具体评估。幸运的是,大部分的服务都是存在同步情况的,于是多线程就显得非常有用处了。

       那超线程神马东东呢。我们回顾一下多线程概念,电脑在执行命令的时候会锁定了下个将被执行的指令的内存储存位置,使CPU精确地知道从哪儿得到这些指令。当一个线程发送到CPU,这线程的内存地址就被锁定,所以CPU明白从哪里开始执行线程。电脑能够递增处理每个指令,一直到处理完一个线程为止。在线程执行以后,电脑就会重新读入下个要执行的指令位置。不同线程可以彼此相互中断,即强迫CPU把电脑上当前处理的结算结果储存在栈里。而这样造成的缺陷就是CPU每次只能处理一个线程。而超线程技术呢?就是让一个CPU可以每次执行一条以上来自不同线程的技术,这样可以减少很大部分的多线程切换操作。不同于提高CPU的时钟速度和增加缓存容量等物理手段,超线程技术可以让系统误以为系统内有两块物理CPU,操作系统就会同时向那‘两’块CPU发送2个线程的任务。在带有超线程技术的CPU上, CPU将会尝试同时执行两个线程(两个线程使用一个cpu上的不同执行单元),因此解决了CPU执行单元利用率低下的问题。不过,如果线程的数目小于物理CPU核数的话,那么其实有无开启超线程其实并没有多大的区别。只有当开启的线程数目大于CPU核数的情况下其优势可能才会体现出来,然而这样的情况也只是在多线程比单线程更适合的程序才可以,即大量的同步通信的程序上其多线程的效果才会可能体现出来。这时候开启超线程有可能会带来收益,而且这些线程的功能点重合越少,效果越明显。而一般的商业网络服务器都存在网络交互的情况,因此超线程可能可以带来一定的提升,然而还是有可能会带来零收益、甚至反作用的,所以需要经过严格的评估测试后再进行决策。

你可能感兴趣的:(并发编程)