PowerShell并行作业与顺序作业-顺序作业更快?

PowerShell并行作业与顺序作业-顺序作业更快?,powershell,Powershell,我试图实现Windows事件日志的多线程解析,在双核系统上,我发现顺序代码比并行代码快得多。以下是一些例子: 顺序: $start = Get-Date $code1 = { Get-WinEvent -Path "D:\logs\hostname-security-20131003005914.evtx" -MaxEvents 200 } $code2 = { Get-WinEvent -Path "D:\logs\hostname-security-20131003015906.evtx"

我试图实现Windows事件日志的多线程解析,在双核系统上,我发现顺序代码比并行代码快得多。以下是一些例子:

顺序:

$start = Get-Date

$code1 = { Get-WinEvent -Path "D:\logs\hostname-security-20131003005914.evtx" -MaxEvents 200 }
$code2 = { Get-WinEvent -Path "D:\logs\hostname-security-20131003015906.evtx" -MaxEvents 200 }

$result1 = & $code1
$result2 = & $code2

$end = Get-Date
$timespan = $end - $start
$seconds = $timespan.TotalSeconds
Write-Host "This took me $seconds seconds in all."
$start = Get-Date

$code1 = { Get-WinEvent -Path "D:\logs\hostname-security-20131003005914.evtx" -MaxEvents 200 }
$code2 = { Get-WinEvent -Path "D:\logs\hostname-security-20131003015906.evtx" -MaxEvents 200 }

$job1 = Start-Job -ScriptBlock $code1 
$job2 = Start-Job -ScriptBlock $code2 

$alljobs = Wait-Job $job1, $job2
$result1, $result2 = Receive-Job $alljobs

$end = Get-Date
$timespan = $end - $start

$seconds = $timespan.TotalSeconds
Write-Host "This took me $seconds seconds in all."
并行:

$start = Get-Date

$code1 = { Get-WinEvent -Path "D:\logs\hostname-security-20131003005914.evtx" -MaxEvents 200 }
$code2 = { Get-WinEvent -Path "D:\logs\hostname-security-20131003015906.evtx" -MaxEvents 200 }

$result1 = & $code1
$result2 = & $code2

$end = Get-Date
$timespan = $end - $start
$seconds = $timespan.TotalSeconds
Write-Host "This took me $seconds seconds in all."
$start = Get-Date

$code1 = { Get-WinEvent -Path "D:\logs\hostname-security-20131003005914.evtx" -MaxEvents 200 }
$code2 = { Get-WinEvent -Path "D:\logs\hostname-security-20131003015906.evtx" -MaxEvents 200 }

$job1 = Start-Job -ScriptBlock $code1 
$job2 = Start-Job -ScriptBlock $code2 

$alljobs = Wait-Job $job1, $job2
$result1, $result2 = Receive-Job $alljobs

$end = Get-Date
$timespan = $end - $start

$seconds = $timespan.TotalSeconds
Write-Host "This took me $seconds seconds in all."
顺序代码运行约5秒(CPU使用率接近50%),而并行代码运行约19秒(CPU使用率接近100%)。我已经对结果进行了回应,以确保它们都是正确的,而且看起来很好

我正在运行Windows8。PowerShell详细信息如下:

Name Value ---- ----- PSVersion 3.0 WSManStackVersion 3.0 SerializationVersion 1.1.0.1 CLRVersion 4.0.30319.18051 BuildVersion 6.2.9200.16628 PSCompatibleVersions {1.0, 2.0, 3.0} PSRemotingProtocolVersion 2.2 17.002秒用于连续测量。
并行时间为14.2秒。

对于您创建的每个作业,将创建一个新的powershell进程,该进程需要用于调度、加载.net运行时等的资源。它会产生大量CPU开销,并且每个作业至少需要20mb以上的内存

因此,工作更适合:

  • 持续数分钟或数小时的长时间运行脚本

  • 在多台计算机上并行运行代码


使用Powershell作业时,Powershell将创建一个新会话以在其中运行scriptblock

试试这个:

measure-command { start-job -ScriptBlock {} }

这就是你创造工作所花费的时间。如果您正在使用作业的任务花费的时间少于此时间,则最好在本地会话中按顺序运行任务。

更多支持此处所述内容的文档,来自Thomas Lee,网址:

“每次运行PowerShell作业时(无论是在ISE还是控制台中),PowerShell将创建PowerShell.exe的实例以执行脚本或脚本块。这意味着每个作业都会带来一些开销–进程创建需要CPU/IO/内存。但是,如果您可以在单独的进程中运行多个任务,则使用Window的多处理功能,这些作业将并行运行,因此需要大量内存至少在理论上是这样


视情况而定。如果正在执行的任务实际执行时使用了大量或资源,那么让多个任务并行运行会提高资源利用率。特别是,对于一个或两个以上的“繁重”任务,您会发现系统正在进行大量分页。这种分页实际上可能会将执行速度降低到并行化的好处被分页成本冲走了。”

虽然这是有道理的,但不幸的是,这并不能解释我所看到的。创造就业机会所需的时间非常少。为了延长任务本身,我将-MaxEvents增加到2000,现在我正在我的工作计算机(四核i7)上运行它。在并行代码中,创建$job1和$job2所需的时间分别为0.18秒和0.11秒。CPU使用率接近50%(使用2个内核)。大约需要49秒。顺序代码在18秒内运行,CPU使用率约为25%。我尝试在并行代码中运行单个作业。也花了约49秒。在Get WinEvent之前和之后向脚本块添加Get Date | Out文件表明,这占用了时间,而不是等待作业或接收作业。因此,在并行作业和顺序代码中的脚本块内运行时,Get WinEvent的行为是不同的。同样的时间差异在我的Windows 8.1机器和服务器2008R2上都很明显(我怀疑桌面操作系统可能在后台放置了并行进程,但在服务器上遇到了相同的结果)。@Rob执行此操作:在收到作业后添加-Keep,然后分别查看每个作业。有开始时间和结束时间的时间戳。这将让你更准确地了解工作本身的情况,我想你会感到惊讶。顺便问一下,您是否尝试过在Powershell工作流中使用并行块?也许对你更有用。@CrownedJitter:谢谢你的建议。使用-keep实际上给出了与我的Get Date hack相同的结果!两个作业的PSBeginTime和PSEndTime完全相同。只是因为一些奇怪的原因,它们需要更长的时间。我编辑了这篇文章的原稿,表明如果你只是简单地使用开始睡眠,情况就不是这样了。一旦脚本块涉及到实时CPU时间,并行就需要更长的时间。我的能力目前还没有扩展到运行空间/工作流,但我会看一看。谢谢。我延长了进程,但正如上面对评论的回复所述,我仍然遇到了违反直觉的结果。我希望能够通过分页来解释这一点,但我的系统没有这样做(系统运行非常少,8GB RAM,SSD上的四核i7)。你能试试这些只在内存中运行的例子吗?顺序:和平行:-如果你不相信长度,数字可以调整。将这些文件另存为单独的PS1文件,并在单独的PS窗口中运行。当并行代码运行时,两个启动的PS进程在进程监视器上分别消耗约46-48%的CPU。代码比顺序代码花费的时间长近10倍。但是,如果我在PowerGUI中运行此代码,并行速度会更快。