在多核机器Linux OS中,当进程调度程序将一个进程迁移到另一个cpu时

时间:2014-04-24 04:32:27

标签: linux fork scheduler multicore

在我的程序中,其rss为65G,当呼叫fork时,sys_clone->dup_mm->copy_page_range将消耗超过2秒。在这种情况下,一个cpu在执行fork时会100%sys,同时,一个线程在fork完成之前无法获得cpu时间。机器有16个CPU,其他CPU空闲。

所以我的问题是一个cpu忙于fork,为什么调度程序不会将等待这个cpu的进程迁移到其他空闲cpu?一般来说,调度程序何时以及如何在cpus之间迁移进程?

我搜索这个网站,现有的线程无法回答我的问题。

1 个答案:

答案 0 :(得分:2)

  

rss是65G,当调用fork时,sys_clone-> dup_mm-> copy_page_range将消耗超过2秒

在执行fork(或clone)时,应将现有流程的vmas复制到新流程的vmas中。 dup_mm function (kernel/fork.c)创建新的mm并进行实际复制。没有直接调用copy_page_range,但我认为,static function dup_mmap可能会被内联到dup_mm,并且会调用copy_page_range

dup_mmap中,锁定了多个锁,包括新mm和旧oldmm

356         down_write(&oldmm->mmap_sem);

获取mmap_sem读写器信号量后,所有mmaps都会循环复制其元信息:

381         for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) 

仅在循环之后(在您的情况下很长),mmap_sem被解锁:

465 out:
468         up_write(&oldmm->mmap_sem);

虽然rwlock mmap_sep被作者拒绝,但没有任何其他读者或作者可以使用oldmm中的mmaps做任何事情。

  

一个线程在fork完成之前无法获得cpu时间   所以我的问题是一个cpu忙于fork,为什么调度程序不会将等待这个cpu的进程迁移到其他空闲cpu?

您确定,其他线程已准备好运行且不想对mmaps执行任何操作,例如:

  • 制作新的东西或取消不需要的东西,
  • 增加或缩小其堆(brk),
  • 增加筹码,
  • pagefaulting
  • 或许多其他活动......?
  

实际上,wait-cpu线程是我的IO线程,它从客户端发送/接收包,在我看来,包总是存在,但是IO线程无法接收它。

你应该检查你的wait-cpu线程的堆栈(甚至还有SysRq),以及那种I / O.文件的mmap是I / O的变体,它将在mmap_sem上被fork阻止。

您还可以检查wait-cpu线程的“上次使用的CPU”,例如在top监视实用程序中,通过启用线程视图(H键)并添加“上次使用的CPU”列来输出(fj更早; f滚动到{ {1}},输入更新)。我认为你的wait-cpu线程可能已经在另一个CPU上,只是不允许(未准备好)运行。

如果您只使用fork来制作P,则对以下内容有用:

  • 切换到exec + vfork(或仅转到exec)。 vfork will suspend您的流程(may not suspend your other threads, it is dangerous),直到新流程执行posix_spawnexec,但执行速度可能比等待复制65 GB的mmaps更快。
  • 或者不使用多个活动线程和多GB虚拟内存从多线程进程执行fork。您可以创建小型(没有多GB mmaped)帮助程序进程,使用ipc或套接字或管道与它进行通信,并要求它进行分叉并执行您想要的任何操作。