0

I'm trying to write at the beginning of my script some code that will ensure every command inside the script is run on just a few specific cores. even if many commands are run in multiple parallels like : [command] & [command] & [command] & [command] & [command] , I want them to only run on the few selected cores.

Currently the script looks for its own PID when it starts, and then feeds that into taskset, where I tell it that its PID is only allowed to use cores 1 to 3.

An example taskset command looks like:

taskset -c 1-3 -p 45678  

But as soon as some parallel commands start, they each get there own PID and are know longer restricted to the allocated cores.

How do I make sure everything in the script stays in the desired cores?

Giles
  • 877
  • 7
  • 18

1 Answers1

1

If you set the CPU for the calling process, then it looks like every child process will have the same settings.

For example, given:

  • A screen session launched using taskset 4 screen

  • In the screen session, 3 instances of top launched

When i have a look (in an other terminal) to the status of top instances:

 for pid in $(ps aux|grep -i top|grep -v grep|awk '{print $2}') ; do taskset -p ${pid} ; done
pid 2505's current affinity mask: 4
pid 2515's current affinity mask: 4
pid 2525's current affinity mask: 4

Here is an example of bash script that do the job:

#!/bin/bash

echo "Setting CPU affinity ..."
# Bind to a given CPU
taskset  -p 4 $$

# Verify it worked
taskset -p $$

echo "Launching background jobs ..."
# Now, launch several background jobs
for i in $(seq 0 10) ; do 
    tail -f /dev/null &
done

echo "Checking ..."
# Now for each instance of background jobs, check CPU affinity
for pid in $(pidof tail) ; do
    taskset -p ${pid}
done

sleep 1

killall tail

And the resulting output:

Setting CPU affinity ...
pid 4313's current affinity mask: f
pid 4313's new affinity mask: 4
pid 4313's current affinity mask: 4
Launching background jobs ...
Checking ...
pid 4327's current affinity mask: 4
pid 4326's current affinity mask: 4
pid 4325's current affinity mask: 4
pid 4324's current affinity mask: 4
pid 4323's current affinity mask: 4
pid 4322's current affinity mask: 4
pid 4321's current affinity mask: 4
pid 4320's current affinity mask: 4
pid 4319's current affinity mask: 4
pid 4318's current affinity mask: 4
./test.sh: line 24:  4317 Terminated              tail -f /dev/null
./test.sh: line 24:  4318 Terminated              tail -f /dev/null
./test.sh: line 24:  4319 Terminated              tail -f /dev/null
./test.sh: line 24:  4320 Terminated              tail -f /dev/null
./test.sh: line 24:  4321 Terminated              tail -f /dev/null
./test.sh: line 24:  4322 Terminated              tail -f /dev/null
./test.sh: line 24:  4323 Terminated              tail -f /dev/null
./test.sh: line 24:  4324 Terminated              tail -f /dev/null
./test.sh: line 24:  4325 Terminated              tail -f /dev/null
./test.sh: line 24:  4326 Terminated              tail -f /dev/null
./test.sh: line 24:  4327 Terminated              tail -f /dev/null
binarym
  • 2,639
  • 9
  • 12
  • This looks like exactly what I need, and its very well explained, but try as I might I can't get it to work – Giles Oct 02 '19 at 13:34
  • I started the script with # Bind to a given CPU taskset -p 4 $$ # Verify it worked taskset -p $$ but then when I stack some loops together in the script, I can see them on htop spreading over all the cores – Giles Oct 02 '19 at 13:35
  • it gets the same feed back at first, except instead of 'current affinity mask: f ' I get 'current affinity mask: ff' I'm guessing I've misunderstood how to implement the code – Giles Oct 02 '19 at 13:40
  • As far as I can tell, this sets 1 pid to a core, but the child pids that build up through the script don't seem to also be restricted :( – Giles Oct 02 '19 at 14:12
  • Then instead of launching binaries directly, why don't you wrap them into a taskset ? just like `taskset ` ? – binarym Oct 02 '19 at 14:44
  • Thanks, just tried that too, but it still seems to be spreading across the cores. I tried: taskset -c 2 [command1] & taskset -c 2 [command2] & taskset -c 2 [command3] but it still just spreads them across all the cores – Giles Oct 03 '19 at 10:37
  • 1
    You may have a problem somewhere else since taskset is supposed to *always* enforce CPU affinity. Did you customized your kernel scheduler ? – binarym Oct 03 '19 at 11:35
  • I haven't knowingly changed my kernel scheduler, but on another Linux OS computer I was able to get this to work using a combination of exec and taskset, so I think you might be right – Giles Oct 04 '19 at 09:22