Processor affinity using Cygwin

I’ve been working on a Python script that takes a long time to run (about 2.5h), and as it was entirely single threaded I figured I’d bind it to a specific core, to reduce cache thrashing, enable clock boosting and such. I wanted a method that worked for arbitrary commands, or I’d use affinity package. The cmd start command always creates a new window, and I wanted the output in my existing shell session. My workaround involves using Powershell to set affinity once the process is running.

winpid () {
    # Find the Windows PIDs of specified Cygwin PIDs, using ps
    local pid=${1:-$$}
    ps -lp "$pid" | sed -ne "s/^. *$pid [ 0-9]\{16\} *\([0-9]\+\).*\$/\1/p"
    while [ $# -gt 1 ] ; do
        shift
        ps -lp "$1" | sed -ne "s/^. *$1 [ 0-9]\{16\} *\([0-9]\+\).*\$/\1/p"
    done
}
setaffinity () {
    local bitmask=$((1<<$1))
    shift
    for wp in `winpid $*` ; do
        powershell -Command "[System.Diagnostics.Process]::GetProcessById($wp).ProcessorAffinity=$bitmask;"
    done
}
withaffinity () {
    local affinity=$1
    shift
    "$@" &
    setaffinity $affinity $!
    fg
}

With these bash functions, I can run “withaffinity 3 somecommand” and have it moved to core 3 specifically.