现在的位置: 首页 > 综合 > 正文

《unix systems for modern architectures》笔记—主从处理器设计和死锁

2013年10月04日 ⁄ 综合 ⁄ 共 1657字 ⁄ 字号 评论关闭

一.主从处理器设计和短期互斥

       短期互斥依赖于内核中绝不会有一个以上的进程同时执行,在MP上实现这一点最简单的技术是要求所有的内核活动都在一个物理处理器上执行,这个处理器为主处理器(master),其余为从处理器(slave),从处理器只能执行用户代码,以用户态执行的进程可以在系统中的任何处理器上执行。但是一旦进入到内核活动,则只能切换到主处理上执行。

       主从处理器设计的中如何做到讲进程分配到各个处理器,有个简单的办法就是使用两个独立的运行队列。一个包含必须运行在主处理器上的内核进程,一个包含运行在从处理器的用户态进程。运行在从处理器上的进程需要进入到内核态时,如系统调用或者trap时将进程添加到主处理器的运行队列中。在主处理做现场切换的时候,如果执行的老进程原来是在用户态执行的,则放到从队列中,否则返回到主队列。

       维护这两个主从队列的互斥使用的是spin lock.自旋锁可以在任何数量处理器的系统上正常工作。

       对于spin lock,如果临界段较短(通常不超过几百行机器指令),那么自旋锁可以工作良好。不应该把它们作为一种长期互斥技术来使用,因为在等候锁的处理器在自旋期间什么有用的工作也不做,系统的性能会降低。

       减少spin lock锁的争用可以使用两种办法,一,内核对不同的临界资源使用不同的锁。二,增强lockunlock,在上锁的时候屏蔽中断,否则,在处理器在获取一个自旋锁的同时锁出现的中断会进一步拖延其他进程等候那个锁的时间。(而且可能导致死锁)

 

二.MP死锁

       最简单的死锁是常见的AB-BA死锁,在两个处理器试图以相反的顺序获得对方的锁,这种动作一定会造成潜在的死锁状态。因为死锁是否真正反正取决于两个处理器之间的相对时间顺序。

       为了防止这类死锁,所有的处理器都必须以相同的次序进行嵌套(nested lock,在代码中,能看到mutex_lock_nested这样的函数。

       除了简单的AB-BA死锁,在别的情况下,自旋锁也可能会出现死锁。例如,如果一个占有自旋锁的进程要执行一次现场切换,那么任何试图获得同一个锁的处理器都会保持自旋,直到占有锁的进程再次恢复运行,并且释放锁为止。这种情况不但系统性能差,还有可能导致死锁。如果系统中所有的处理器都试图获得一个已经被现场切换出去的进程占有的自旋锁,那么一旦处理器开始为锁而自旋,它们就不能执行现场切换。这就意味占有自旋锁的进程不能重执行,而再也没机会释放锁。为了这种死锁问题的发生,不允许一个进程跨越现场切换还能占有一个自旋锁。

      递归死锁也是一个比较常见的死锁。如果一个处理器已经锁住自旋锁,而且在该处理器上发生一次中断,那么中断处理程序企图获得同一个锁,就会导致死锁。处理器会在中断级上永远自旋下去,而被中断的进程再也没机会释放锁了。出于这个原因,在一个中断处理程序要使用spin
lock
时,基准内核代码在获取锁时要屏蔽中断的发生。Spin_trylock也能间接解决死锁问题,再未获取到锁资源时返回0,获取到锁资源则返回1.

 

三.主从处理器性能和改进

       在理想情况下,SMP的整体系统吞吐量将等于处理器的数量和单个处理器吞吐量的积。     有两个基准来评价性能,一个基准有一组完全限于计算的进程组成。一旦启动,它们不会产生缺页错,无系统调用,不执行IO操作,另一个基准由相同数量的进程组成,不同在于这些进程都是限于系统调用的。

    对于主从处理器设计,基准一能很好的应用,但是对于多系统调用操作的基准,性能没有改善,因为所有的内核操作均在在同一个core上执行。
    通过放松所有的系统调用都在主处理上执行这一要求,能改善主从处理器内核实现的性能。任何返回内核信息的系统调用都可以有从处理器来执行。
    但是该方法只能改善,问题的本质在于将所有内核活动都限制到一个处理器上的设计上,所以唯一的办法是让所有处理器在都同时在内核中处理。

抱歉!评论已关闭.