如何在多个核心上运行使用bash传输的进程?

P S*_*ved 11 linux bash multicore scheduling process

我有一个简单的bash脚本,它将一个进程的输出传递给另一个进程.即:.

dostuff | filterstuff
Run Code Online (Sandbox Code Playgroud)

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

系统的哪个组成部分负责,以及我应该如何利用多核功能?

请注意,2.6.30内核没有这样的问题.

澄清:遵循丹尼斯威廉姆森的建议,我确保使用顶级程序,管道进程确实总是运行在同一个处理器上.Linux调度程序,通常做得非常好,这次不做.

我认为bash中的某些内容会阻止操作系统执行此操作.问题是,我需要一个适用于多核和单核机器的便携式解决方案.Dennis Williamson提出的taskset 解决方案不适用于单核机器.目前我正在使用:,

dostuff | taskset -c 0 filterstuff 
Run Code Online (Sandbox Code Playgroud)

但这似乎是一个肮脏的黑客.有人能提供更好的解决方案吗?

Pau*_*ce. 7

尝试设置CPU(处理器)亲和性:

taskset -c 0 dostuff | taskset -c 1 filterstuff
Run Code Online (Sandbox Code Playgroud)

编辑:

试试这个实验:

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

    #!/bin/bash
    while true
    do
      ps
      sleep 2
    done  
    
    Run Code Online (Sandbox Code Playgroud)
  • 开始这个运行:

    ./proctest | grep bash
    
    Run Code Online (Sandbox Code Playgroud)
  • 在另一个终端,开始顶部 - 确保它按%CPU排序
  • 让它稳定几秒钟,然后退出
  • 发出命令 ps u
  • top -p最常见的几个进程的PID列表开始,比如8个,从屏幕上留下的列表中退出top加上的列表proctestgrep列出的ps- 全部用逗号分隔,就像这样(顺序没有'重要):

    top -p 1234, 1255, 1211, 1212, 1270, 1275, 1261, 1250, 16521, 16522
    
    Run Code Online (Sandbox Code Playgroud)
  • 加处理器字段-按f然后j然后Space
  • 排序设置为PID -按Shift+ F然后aSpace
  • 可选:按Shift+ H打开线程视图
  • 可选:按d,然后按,.09然后按Enter设置短延迟时间
  • 现在看着流程从处理器移动到处理器,你应该看到proctestgrep反弹,有时在同一个处理器上,有时在不同的处理器上

  • 有关更多信息,请参阅`man sched_setscheduler`和`man cpuset`.Linux在调度方面做得很好.尝试运行`top`并按fj <space>添加处理器(P)字段,您将看到不同的进程在不同的CPU上运行. (2认同)

eph*_*ent 7

假设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内核邮件列表,以便他们可以调整其启发式.