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

Fast Switching of Threads Between Cores

2013年10月22日 ⁄ 综合 ⁄ 共 3415字 ⁄ 字号 评论关闭
 

作者:Dean Tullsen   Richard Strong      ACM SIGOPS     2009.02

这篇文章主要是提出了一种改进的快速的线程切换方法,减少线程在不同的core之间切换时的开销。

基于linux2.6.18内核,作者提出了两种改进的方法,并对每种方法做了详细的测试数据分析和性能评价,个人感觉这篇论文给我们了一个启示,熟读内核,。。。。。。。。。

我们下来看下作者实现的成果:

(1)内核切换的延迟减少了一半甚至更多,比起现在的内核切换机制

(2)提出了几种基于软件的减少内核切换代价的实现方法

(3)在真机和模拟器上编写了测试用的benchmarks

现在先来介绍一下现有的线程在内核间切换的方法,以便理解本文提出的方法(以linux2.6.23前的代码为例)

1 linux2.6.23之前的不同内核之间的线程切换机制(个人意见,有错请指正)

当某个线程想要切换到或将要被切换到其他core上时,首先把自己放在一个每CPU变量的迁移队列上,然后唤醒或是把控制权交给一个进程,可以叫它
“迁移进程”,这个进程每个core都有一个,感觉应该是每个物理
core有一个(不确定)。这个进程来完成真正的把要迁移的进程放到目标core的运行队列上,这时候就会有几种情况:

(1)如果目标core是idle的,“迁移进程”就会发一个signal给目标core,来触发它执行schedule()

(2)如果目标core不出于idle.“迁移进程”就什么也不做

做完上面的操作后,“迁移进程”返回,即再切换到原来的schedule().从运行队列中再选择一个进程来运行。

从这个过程我们可以看出,进行了两次进程的切换,即先要切换到"迁移进程",然后再从“迁移进程”切换回。  作者的目的就是想在某些情况下,减少这种上下文的切换,从而实现一种快速的切换机制。

2 作者提出的快速的不同cores之间的线程切换机制

方法一:新加一个实现不同core之间线程切换的系统调用switchcores,另外重新优化现有内核的schedule()

基本思想是:

不改变schedule()的参数,但是在thread_info中新增加了一个数据成员CPUID(具体之cpu core
ID),如果这个数据成员被置位的话,schedule将会无条件的把当前选中的或正在执行的线程T移出运行队列,并把它放到一个每CPU或是每core
队列中,文中把这个队列叫做AQ(alternate
Queue),然后重新返回原来的schedule()代码执行,去选择下一个要运行的进程假设是N来运行,当进程N运行之前,它先去检查AQ这个队列,
如果发现它不为空,就会把队列上的线程一个个的发送CPUID指定的目标core的运行队列上去,并且给目标core发送一个信号,触发目标core调用
schedule()。

方法二:提出并实现了一种作者成为fast-paths的schedule()

由于这个思想也比较简单,就直接看这段伪代码。

sendpix0sendpix1

这部分的原理代码已经写的非常清楚,需要稍微说明的一点就是fast_schedule_source中删除了检查AQ的几句代码,主要原因是这部分在schedule中已经做了!

其实文中还提到了IPI,但是因为代价太高,没有被采用

3 通过上面的分析我们可以想到虽然这种机制减少了切换,但是必须显示的指明需要进行不同core之间的线程切换才行,这就引出一个非常重要的问题:切换的时机是什么?

我们也会很自然的想到,增加系统调用是最好的显示声明,作者也是增加了corewitch(destcoreset,flags)系统调用,由flags来决定不同的切换的策略,比如说是否有CPU的亲和性等等。

文中给出了一个实例!

作者:Dean Tullsen   Richard Strong      ACM SIGOPS     2009.02

这篇文章主要是提出了一种改进的快速的线程切换方法,减少线程在不同的core之间切换时的开销。

基于linux2.6.18内核,作者提出了两种改进的方法,并对每种方法做了详细的测试数据分析和性能评价,个人感觉这篇论文给我们了一个启示,熟读内核,。。。。。。。。。

我们下来看下作者实现的成果:

(1)内核切换的延迟减少了一半甚至更多,比起现在的内核切换机制

(2)提出了几种基于软件的减少内核切换代价的实现方法

(3)在真机和模拟器上编写了测试用的benchmarks

现在先来介绍一下现有的线程在内核间切换的方法,以便理解本文提出的方法(以linux2.6.23前的代码为例)

1 linux2.6.23之前的不同内核之间的线程切换机制(个人意见,有错请指正)

当某个线程想要切换到或将要被切换到其他core上时,首先把自己放在一个每CPU变量的迁移队列上,然后唤醒或是把控制权交给一个进程,可以叫它
“迁移进程”,这个进程每个core都有一个,感觉应该是每个物理
core有一个(不确定)。这个进程来完成真正的把要迁移的进程放到目标core的运行队列上,这时候就会有几种情况:

(1)如果目标core是idle的,“迁移进程”就会发一个signal给目标core,来触发它执行schedule()

(2)如果目标core不出于idle.“迁移进程”就什么也不做

做完上面的操作后,“迁移进程”返回,即再切换到原来的schedule().从运行队列中再选择一个进程来运行。

从这个过程我们可以看出,进行了两次进程的切换,即先要切换到"迁移进程",然后再从“迁移进程”切换回。  作者的目的就是想在某些情况下,减少这种上下文的切换,从而实现一种快速的切换机制。

2 作者提出的快速的不同cores之间的线程切换机制

方法一:新加一个实现不同core之间线程切换的系统调用switchcores,另外重新优化现有内核的schedule()

基本思想是:

不改变schedule()的参数,但是在thread_info中新增加了一个数据成员CPUID(具体之cpu core
ID),如果这个数据成员被置位的话,schedule将会无条件的把当前选中的或正在执行的线程T移出运行队列,并把它放到一个每CPU或是每core
队列中,文中把这个队列叫做AQ(alternate
Queue),然后重新返回原来的schedule()代码执行,去选择下一个要运行的进程假设是N来运行,当进程N运行之前,它先去检查AQ这个队列,
如果发现它不为空,就会把队列上的线程一个个的发送CPUID指定的目标core的运行队列上去,并且给目标core发送一个信号,触发目标core调用
schedule()。

方法二:提出并实现了一种作者成为fast-paths的schedule()

由于这个思想也比较简单,就直接看这段伪代码。

sendpix0sendpix1

这部分的原理代码已经写的非常清楚,需要稍微说明的一点就是fast_schedule_source中删除了检查AQ的几句代码,主要原因是这部分在schedule中已经做了!

其实文中还提到了IPI,但是因为代价太高,没有被采用

3 通过上面的分析我们可以想到虽然这种机制减少了切换,但是必须显示的指明需要进行不同core之间的线程切换才行,这就引出一个非常重要的问题:切换的时机是什么?

我们也会很自然的想到,增加系统调用是最好的显示声明,作者也是增加了corewitch(destcoreset,flags)系统调用,由flags来决定不同的切换的策略,比如说是否有CPU的亲和性等等。

文中给出了一个实例!

sendpix2

做到动态的指示切换的时机,可以在考虑下!

4 作者利用M5测试了修改过的程序的运行

5 文中还提到了:在实际的多核机器上,让一些CPU处于idle状态能明显的降低功耗,这是否可以启发我们不要一味的追逐负载平衡,设计一种间接的公平调度机制呢?

今天就写到这吧!

总体感觉这篇文章很清新,很小的一个方面,很少的代码修改,就能写出一篇不错的文章。而且,这种文章更有实用性!!!!!

sendpix2

做到动态的指示切换的时机,可以在考虑下!

4 作者利用M5测试了修改过的程序的运行

5 文中还提到了:在实际的多核机器上,让一些CPU处于idle状态能明显的降低功耗,这是否可以启发我们不要一味的追逐负载平衡,设计一种间接的公平调度机制呢?

今天就写到这吧!

总体感觉这篇文章很清新,很小的一个方面,很少的代码修改,就能写出一篇不错的文章。而且,这种文章更有实用性!!!!!

抱歉!评论已关闭.