CPUとIOを集中的に使用するスケジュールされたタスクがあり、実行に約4時間かかります(好奇心旺盛な場合はソースコードをビルドします)。タスクは、その作業を行うためにさまざまなサブプロセスを生成するPowershellスクリプトです。 Powershellプロンプトから対話的に同じプロセスを実行すると、同じユーザーアカウントとして、約2時間半で実行されます。タスクはWindows Server 2008 R2で実行されています。
私が知りたいのは、スケジュールされたタスクとして実行するのに1時間以上もかかる理由です。私が気づいたことの1つは、タスクスケジューラが通常以下の優先度で実行されるため、タスクが開始すると、同じ優先度を引き継いだことです。ただし、Powershellプロセスの優先順位を通常に戻すようにスクリプトを更新しましたが、それでも同じくらいの時間がかかります。
誰かが2つのシナリオの何が違うのか考えていますか?プロセッサとIO負荷の違いを除外しました-このタスクはシステムが使用される唯一のものであるため、リソースを奪い合う可能性のある実行中のものは他にありません。
ここでの作業には、「通常の」プロセスの優先順位だけではないようです。質問で述べたように、タスクスケジューラはデフォルトでタスクを通常の優先度よりも低く実行します。 StackOverflow に関するこの質問では、タスクを通常の優先度で実行するように修正する方法について説明していますが、修正により、メモリの優先度というわずかに異なる点が1つ残っています。メモリの優先順位はWindows Vistaの新機能であり、 このTechnetの記事 で説明されています。 Process Explorer を使用してメモリの優先順位を確認できます。これは、管理者またはプログラマーにとって必須のツールです。
とにかく、スケジュールされたタスクの優先度を修正しても、タスクのメモリの優先度は4に設定されます。これは、通常の設定である5より1ノッチ下です。手動でタスクのメモリの優先度を5に上げると、パフォーマンスはオンになりましたプロセスをインタラクティブに実行するのと同じです。
優先度を上げる方法については、 関連するStackOverflow質問への私の回答を参照してください IO priority;メモリの優先度の設定は同様に、NtSetInformationProcessを介して、PROCESS_INFORMATION_CLASS
をProcessMemoryPriority
に設定します(この値は39または0x27です)。他の人が必要とし、プログラマツールにアクセスできない場合は、これを設定するために使用できる無料のユーティリティを作成する場合があります。
編集:私は先に進んで、タスクのメモリ優先度を照会および設定するための無料のユーティリティを記述しました ここから入手できます 。ダウンロードには、ソースコードとコンパイル済みバイナリの両方が含まれています。
問題は、プロセスが低いI/O優先度と低いメモリ優先度で始まっていることです。これを確認する最も簡単な方法は、sysinternalsのProcess Explorerを使用することです。このスケジュールされたタスクから生成されたプロセスのプロパティを見ると、そのプロセスのI/O優先度が低く、メモリ優先度が2であることがわかります。
この問題の解決策は次のとおりです。
<Priority>7</Priority>
のような行が見つかります残念ながら、GUIからスケジュールされたタスクの初期優先順位を変更する方法はありません。
おそらく、スケジュールされたタスクはデフォルトで低い優先度で実行されます。
優先順位を高くするには、prio
を使用します。
ユーザーXとしてスケジュールされたタスクとして実行するように設定し、実行する前にユーザーXとしてログインすると、実行時にセッションでウィンドウが開き、セッションで実行されます。
これを行うと、時間がかかりますか、それとも短くなりますか?これが何を意味するのかはわかりませんが、差別化に役立つかもしれません。ログイン時にユーザーアカウントが持つネットワークアクセスがあり、スケジュールされたタスクとして実行されていない場合、タイムアウトして失敗する必要がありますか?新しいユーザーアカウントを作成し、そのアカウントでスケジュールされたタスクとして実行した場合、動作は異なりますか?
別のアイデア:スケジュールされたタスクとして実行する場合-スクリプトの優先度を修正したので、サブプロセスはすべて通常または通常以下として実行されますか?
優先度を設定するためのPowerShellのスニペットを次に示します(リモートPowerShellセッションで機能します!):
$taskName = "MyTask" ;`
$currentTask = Get-ScheduledTask -TaskName $taskName ;`
$settings = $currentTask.Settings ;`
$settings.Priority = 4 ;`
Set-ScheduledTask -TaskName $taskName -Settings $settings
最初は、通常より高い優先度を使用できます(たとえば、高)
2番目に-フォアグラウンドセッションがいくつかのリソース、主にハードディスクIOとメモリを必要とするため、スケジュールされたタスクが少なくなることを理解する必要があります。明確なベンチマークについては、Powershellスクリプトの実行中にログオフする必要があります。
さらに、メモリを追加したり、ramdriveを使用したり、複数のハードディスクで作業を分割してプロセスを高速化したりすることもできます
この質問はしばらく前からで、Windows Server 2008R2向けです。同じ質問がありましたが、Windows 10の場合です。Windows10(1703および1809で検証済み)では、インポートされたxmlを使用して「優先度」を4に設定するだけで、同じ基本優先度、動的優先度、I/O優先度を得ることができます、および対話的に開始されるプロセスとしてのメモリ優先度。