3

When using Powershell Jobs, Runspaces, or Workflows, are the threads being executed on separate cores? (and if so, how do we tell powershell how many cores to use? -- sorry that's 2 questions.)

.Net has the Task Parallel Library, which allows a 'for loop' to run in parallel, using all available cores (here is one example). Does Powershell Jobs, Runspaces, or Workflows do something similar? And by similar, I mean are the threads actually running on separate cores, in parallel?

I found a similar question here, but it seems unclear (to me anyway) if the threads are executed on separate cores. It seems that sometimes multi-threads are mistaken for parallel, as mentioned here.

If using multiple cores with Powershell is not possible, I will use C# or perhaps Python, but my first choice is to use Powershell because (insert long list of reasons).

If it's relevant, I'm trying to do all this to help a co-worker who does server admin type stuff. Currently, his powershell script loops through a list of servers, and foreach server, does stuff. Currently the script runs on an 8 core machine, but is only using one core. I'm sure there are other ways to boost performance, but doing it in parallel is my current goal.

greg
  • 338
  • 7
  • 17

1 Answers1

2

I would say yes if by separate cores, you mean logical cores (not physical cores). Run something like this and notice the output from “$num”. $num represents the current logical (not physical) core on which a thread is running. If this script runs on a dual core machine (with 4 logical cores), the output of $num is a 0, 1, 2, or 3. See here for a better explanation on Logical vs Physical CPU.

$sb = {
    param($sbarg)
$MethodDefinition = @'
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
public static extern int GetCurrentProcessorNumber();
'@

    $Kernel32 = Add-Type -MemberDefinition $MethodDefinition -Name 'Kernel32' -Namespace 'Win32' -PassThru

    0..10 | % {
    $num = $Kernel32::GetCurrentProcessorNumber() 
    Write-Output "[$sbarg]:[$_] on '$num'"

    # simulate some work that may make the cpu busy
    # perhaps watch in task manager as well to see load
    $result = 1; foreach ($number in 1..1000000) {$result = $result * $number};

    Start-Sleep -Milliseconds 500
    }
}

0..10 | % {
    Start-Job -ScriptBlock $sb -ArgumentList $_
}

Get-Job

# Wait for it all to complete
While (Get-Job -State "Running")
{
    Write-Output "waiting..."
    Start-Sleep 2
}

# Getting the information back from the jobs
Get-Job | Receive-Job

# Clean Up
Get-Job | Remove-Job
greg
  • 338
  • 7
  • 17
Kory Gill
  • 6,993
  • 1
  • 25
  • 33