关于单线程和多CPU的问题

来源:互联网 发布:php程序员的工作状态 编辑:程序博客网 时间:2024/05/23 10:46

指令是存在前后顺序和逻辑关系的,比如一个运算要计算2*3+1,那如果需要拆解成一个cpu执行乘法一个cpu执行加法,没有执行完乘法是没有办法执行加法的.程序代码也一样,单线程就代表了指令只能以一个队列的形式进行依次处理,没办法并发。
现在倒是有CPU可以在单线程的时候自动超频,也就是趁着别的几个核心没有工作,把自己当前繁忙的核心的频率提高。也算是对单线程程序的一种补救和兼容。
指令级别的重排序,是在CPU中进行的。部分情况下,会有将串行的几个指令拆分为并行的情况出现。但这不能与多线程相比,大多数情况下指令是无法拆分为并行计算的。现有的CPU指令级优化,更多的是进行前后顺序调换,达到减少读写内存,或合并多步计算的效果。
这里写图片描述
这种指令重排是有限制的,为了保证多线程程序的正确性(线程之间的数据可见性),往往需要编译器和程序员故意降低CPU重排序的优化程度。这就是所谓不同语言定义的内存模型。
上图是内存模型对比,性能就是指令重排序的程度,性能越高证明指令重排序程度越高。蓝色是三种语言虚拟的内存模型(JMM是java语言的),它们都是对红色CPU内存模型的一种包装和处理。编译器会想办法欺骗CPU,禁止一些不希望出现的指令重排序,以便保证一个相对简单的编程内存模型。可以看出,我们还是需要以优化算法为主,CPU指令重排只是其次。
程序算法就像是数学题的解法,多线程就像是聪明人想出的数学题的简便算法。而指令重排这种优化,更像是心算口诀,是一种更低层次的优化。心算口诀能够加快计算,但是它没有办法代替好的算法。
实现多线程也是一样,虽然有些CPU可以在一定程度上改变小范围内的指令顺序,达到并行处理几条指令的效果。但是这都只是低层次的优化,而且现在的大部分CPU都没有办法将串行指令有效的拆分为并行指令。
严格上说,单线程程序在部分代码片段中,有可能被CPU将指令安排在多个核心进行并行运算,但是这和整体程序指令数量相比是极少的情况。CPU是在极其微观的汇编级别进行的优化,有固定的优化定律的,根据内置的“定律”,CPU判断出前后两条语句没有数据和逻辑上的依赖性,则可以将它们并行计算。在一个小程序的上百万行汇编指令中,还是能发现一些可以并行计算的片段的。但正如前面我描述的,由于这是在最微观的层面上依据一些“定律”进行优化,这就使得优化的余地很少。就像优化一道复杂的数学题算法和优化一个简单的方程解法的区别,越宏观越复杂的东西,越有优化的余地。
为了追求更高的优化程度,CPU制订了内存模型,它是一些对程序的“前提假设”。正是由于有了这种假设,CPU所“看到”(也就是CPU可以预见的)代码更多了,所面对的优化问题更复杂,对程序优化的程度就能更大些。但正是这些“前提假设”导致了编程规则更复杂,编程难度会变得更大。

0 0
原创粉丝点击