如何在多核上运行使用bash进行pipe理的进程?

我有一个简单的bash脚本,pipe道输出到另一个进程。 即:。

dostuff | filterstuff 

碰巧在我的Linux系统(openSUSE,如果它很重要的话,kernel 2.6.27),这两个进程都运行在一个内核上。 但是,在不同内核上运行不同的进程是一种默认策略,在这种情况下不会触发。

系统的哪个部分负责,我该怎么做来利用多核function?

请注意 ,在2.6.30内核上没有这样的问题。

澄清 :遵循丹尼斯·威廉姆森的build议,我确定了顶级程序,pipe道进程确实总是运行在同一处理器上。 Linux调度程序,通常做得非常好,这次不行。

我认为,在bash中的东西可以防止操作系统做到这一点。 问题是我需要一个适用于多核和单核机器的便携式解决scheme。 Dennis Williamson提出的taskset 解决scheme不适用于单核机器。 目前我正在使用:,

 dostuff | taskset -c 0 filterstuff 

但这似乎是一个肮脏的黑客。 谁能提供更好的解决scheme?

Solutions Collecting From Web of "如何在多核上运行使用bash进行pipe理的进程?"

假设dostuff在一个CPU上运行。 它将数据写入管道,并且该数据将在该CPU的缓存中。 由于filterstuff正在读取管道,因此调度程序决定在同一个CPU上运行它,以便其输入数据已经在缓存中。

如果你的内核是用CONFIG_SCHED_DEBUG=y构建的,

  #echo NO_SYNC_WAKEUPS> / sys / kernel / debug / sched_features 

应该禁用这个启发式的类。 (有关其他调度程序可调参数,请参阅/usr/src/linux/kernel/sched_features.h/proc/sys/kernel/sched_*

如果这有帮助,并且问题仍然存在于一个新的内核中, 并且在单独的CPU上运行真的比一个CPU运行得更快,请将问题报告给Linux内核邮件列表,以便他们调整启发式。

给这个尝试设置CPU(处理器)亲和力:

 taskset -c 0 dostuff | taskset -c 1 filterstuff 

编辑:

试试这个实验:

  • 创建一个名为proctest的文件,并将chmod +x proctest作为内容:

     #!/bin/bash while true do ps sleep 2 done 
  • 开始这个运行:

     ./proctest | grep bash 
  • 在另一个终端中,从头开始 – 确保按%CPU排序
  • 让它解决几秒钟,然后退出
  • 发出命令ps u
  • 用列表中最高的几个进程(比如说8个)从top -p列表中选择top -p ,列出了由ps列出的proctestgrep的列表 – 所有列表都由逗号隔开,像这样(顺序无关紧要):

     top -p 1234, 1255, 1211, 1212, 1270, 1275, 1261, 1250, 16521, 16522 
  • 添加处理器字段 – 按f然后j然后空格
  • 设置排序PID – 按Shift + F然后一个 空间
  • 可选:按Shift + H打开线程视图
  • 可选:按d键入.09 ,然后按Enter键设置一个短暂的延迟时间
  • 现在看着进程从一个处理器移动到proctest处理器,你应该看到proctestgrep反弹,有时在同一个处理器上,有时在不同的处理器上

Linux调度程序旨在提供最大的吞吐量,而不是做你认为最好的。 如果你正在运行与管道连接的进程,很有可能其中一个阻塞另一个进程,然后交换。 在单独的内核上运行它们将获得很少或没有,所以它不会。

如果你有两个任务都是真正准备好在CPU上运行,我希望看到他们在不同的内核上(在某些时候)。

我的猜测是,会发生什么事情,dostuff运行,直到管道缓冲区变满,在这一点上,它不能再运行,所以“filterstuff”进程运行,但运行这么短的时间,dostuff不会得到重新调度,直到filterstuff完成对整个管道缓冲区的过滤,然后dostuff再次被调度。