Powershell 多线程数学
Posted
技术标签:
【中文标题】Powershell 多线程数学【英文标题】:Powershell Multithreaded math 【发布时间】:2015-10-22 12:40:25 【问题描述】:我目前正在从事一个学习 powershell 的自我启发项目,并且一直在编写一个脚本来生成素数。就目前而言,该脚本可以正常运行,但我的下一个目标是提高它的处理速度。
cls
$Primes = @()
$Primes += 3
$TargetNum = 5
$PrimesIndex = 0
$NumOfPrime = 3
while(1)
if(($TargetNum / 3) -lt 3)
$Primes += $TargetNum
$TargetNum += 2
$NumOfPrime += 1
else
if($Primes[$PrimesIndex] -le ($TargetNum / ($Primes[$PrimesIndex])))
if($TargetNum % $Primes[$PrimesIndex] -eq 0)
$PrimesIndex = 0
$TargetNum += 2
else
$PrimesIndex++
else
$PrimesIndex = 0
$NumOfPrime += 1
$Primes += $TargetNum
$TargetNum += 2
if($TargetNum -gt 100000)write-host $TargetNum ", " $NumOfPrime;break
如果我执行 Measure-command & ".\primes.ps1"
语句,它将在 ≈ 9.1 秒内计算前 100,000 个素数(无论如何对我来说),但这只是使用单个 CPU 线程执行计算。
我已经研究过使用start-job
和start-process
commands 来实现某种多线程,但我无法理解它们是如何工作的。
如果我将主要测试计算转移到一个函数中,我将如何在所有 4 个逻辑内核中调用该函数?也许创建第二个 powershell 脚本,我可以将一个值传递给测试,然后启动它?上面的脚本在前 10 秒内平均解决了 10,000 个 primes\sec,powershell 甚至能够如此快速地启动和停止一些工作脚本吗?
【问题讨论】:
【参考方案1】:必须分别考虑两个术语:异步和并行编程。第一个提供任意任务的简单后台执行,而后者要求您(作为算法的作者)将您的任务分成几个独立的任务,以便能够在单独的计算单元(内核、处理器、机器)上运行它们。
您可以轻松地使用您的函数启动异步任务,但它不会为您提供并行计算:
Start-Job -Name "GetPrimes" -ScriptBlock MyPrimesFunction | Wait-Job | Receive-Job
实现并行性的一种简单方法是将函数拆分为块(例如,通过几个数字间隔来搜索素数),然后使用Start-Job
运行每个块:
$jobs = @()
# gather all jobs into an array
$jobs += Start-Job -ScriptBlock MyPrimesFunction1
$jobs += Start-Job -ScriptBlock MyPrimesFunction2
$jobs += Start-Job -ScriptBlock MyPrimesFunction3
$jobs += Start-Job -ScriptBlock MyPrimesFunction4
# wait for all jobs
Wait-Job $jobs | Out-Null
# get result arrays from jobs
$results = $jobs | Receive-Job
$primes = @()
# merge results into single array
foreach ($result in $results)
$primes += $result
请注意,您的函数必须以素数数组的形式返回结果。而且你必须重写你的函数 4 次,每次使用不同的数字间隔。
作业方法依赖于系统进程管理(因为每个作业都启动单独的 powershell.exe)。另一种方法是使用运行空间。你可以阅读several posts about it。
【讨论】:
以上是关于Powershell 多线程数学的主要内容,如果未能解决你的问题,请参考以下文章
发布支持多线程的PowerShell模块 —— MultiThreadTaskRunner
如何使用PowerShell多线程并使用Pester Mocks进行单元测试