2012-05-22 5 views
11

私は、Windowsで新しいプロセスを作成するのは非常に高価だと聞いています。しかし、私は正確な数を見つけることができません。球場のサイクル数はありますか? 2GHzのデュアルコアプロセッサでは何ミリ秒ですか?Windowsでのプロセス作成のオーバーヘッドは何ですか?

私はPythonでテストプログラムを作成し、プロセスごとに5msを測定しましたが、どれがPythonの余分なオーバーヘッドか分かりません。私はあまり推測していない。

+0

最近のサイクルでは、CPUのサイクルは同じ意味を持ちませんでした。スレッドとプロセスはどちらもカーネルオブジェクトなので、カーネルモードへの移行は少なくとも1回は必要です。それ以外の場合は、Windowsのバージョン(Shimsを考慮)にも依存します。 – 0xC0000022L

+0

関連するディスカッション(回答ではありません):http://stackoverflow.com/questions/47845/why-is-creating-a-new-process-more-expensive-on-windows-than-linux – assylias

+0

プロセスモニタ(MSウェブサイトから入手可能)を使用し、新しいプロセスの開始を見て、このスケールのアイデア。ファイルとレジストリの操作が*千*発生しています。 –

答えて

18

質問があります。

前述のように、オーバーヘッドは高いです。好奇心から、スレッドとプロセスの作成にどれくらいの時間がかかり、これらの時間がどのように関連しているかを、親指で確認するためのベンチマークを書きました。

#include <windows.h> 
#include <stdio.h> 
#include <conio.h> 

#define MIN 0 
#define AVG 1 
#define MAX 2 

DWORD WINAPI thread(LPVOID lpvData) 
{ 
    return (0); 
} 

int main() 
{ 
    BOOL result; 
    int iteration; 
    int i; 
    STARTUPINFO si; 
    PROCESS_INFORMATION pi; 
    DWORD tStart; 
    DWORD tEllapsed; 
    double tCall; 
    int spawnCount; 
    HANDLE hThread; 
    DWORD threadId; 
    double ratio; 
    double statCreateProcess[3]; 
    double statCreateThread[3]; 


    for (iteration = 0; iteration < 16; iteration++) 
    { 
     /* 
     ** Measure creation time of process 
     */ 
     tEllapsed = 0; 
     spawnCount = 0; 
     for (i = 0; i < 100; i++) 
     { 
      ZeroMemory(&si, sizeof(si)); 
      si.cb = sizeof(si); 
      ZeroMemory(&pi, sizeof(pi)); 

      tStart = GetTickCount(); 
      result = CreateProcess(NULL, 
            "cmd.exe", 
            NULL, 
            NULL, 
            FALSE, 
            NORMAL_PRIORITY_CLASS, 
            NULL, 
            NULL, 
            &si, 
            &pi); 

      if (result != FALSE) 
      { 
       tEllapsed += GetTickCount() - tStart; 
       spawnCount++; 

       // clean up... 
       TerminateProcess(pi.hProcess, 0); 
       CloseHandle(pi.hThread); 
       CloseHandle(pi.hProcess); 
      } 
     } 
     tCall = tEllapsed/(double)spawnCount; 
     printf("average creation time of process: %0.3fms\n", tCall); 

     // track statistics... 
     if (iteration > 0) 
     { 
      if (statCreateProcess[MIN] > tCall) 
       statCreateProcess[MIN] = tCall; 
      statCreateProcess[AVG] += tCall; 
      if (statCreateProcess[MAX] < tCall) 
       statCreateProcess[MAX] = tCall; 
     } 
     else 
     { 
      statCreateProcess[MIN] = tCall; 
      statCreateProcess[AVG] = tCall; 
      statCreateProcess[MAX] = tCall; 
     } 


     /* measure creation time of thread */ 
     spawnCount = 0; 
     tStart = GetTickCount(); 
     for (i = 0; i < 5000; i++) 
     {   
      hThread = CreateThread(NULL, 
            0, 
            thread, 
            NULL, 
            0, 
            &threadId); 
      if (hThread != NULL) 
      { 
       spawnCount++; 

       // clean up... 
       CloseHandle(hThread); 
      } 
     } 
     tEllapsed = GetTickCount() - tStart; 
     tCall = tEllapsed/(double)spawnCount; 
     printf("average creation time of thread: %0.3fms\n", tCall); 

     // track statistics... 
     if (iteration > 0) 
     { 
      if (statCreateThread[MIN] > tCall) 
       statCreateThread[MIN] = tCall; 
      statCreateThread[AVG] += tCall; 
      if (statCreateThread[MAX] < tCall) 
       statCreateThread[MAX] = tCall; 
     } 
     else 
     { 
      statCreateThread[MIN] = tCall; 
      statCreateThread[AVG] = tCall; 
      statCreateThread[MAX] = tCall; 
     } 
    } /* for (iteration = ...) */ 

    statCreateProcess[AVG] /= iteration; 
    statCreateThread[AVG] /= iteration; 

    printf("\n\n--- CreateProcess(..) ---\n"); 
    printf("minimum execution time ...: %0.3fms\n", statCreateProcess[MIN]); 
    printf("average execution time ...: %0.3fms\n", statCreateProcess[AVG]); 
    printf("maximum execution time ...: %0.3fms\n", statCreateProcess[MAX]); 
    printf("\n--- CreateThread(..) ---\n"); 
    printf("minimum execution time ...: %0.3fms\n", statCreateThread[MIN]); 
    printf("average execution time ...: %0.3fms\n", statCreateThread[AVG]); 
    printf("maximum execution time ...: %0.3fms\n", statCreateThread[MAX]); 

    ratio = statCreateProcess[AVG]/statCreateThread[AVG]; 
    printf("\n\nratio: %0.3f\n\n", ratio); 

    getch(); 
    return (0); 
} 

私は自分のコンピュータ上で数回(のi5 3.2GHzの、Windows 7の)を作ったとアンチウイルスアプリケーションをオフにすると、ベンチマークは、Visual Studioの外から開始された場合の値はかなり一致している。

--- CreateProcess(..) --- 
minimum execution time ...: 11.860ms 
average execution time ...: 12.756ms 
maximum execution time ...: 14.980ms 

--- CreateThread(..) --- 
minimum execution time ...: 0.034ms 
average execution time ...: 0.037ms 
maximum execution time ...: 0.044ms 


ratio: 342.565 

期待されるように、より多くのシステムコールが関与し、別のスレッドによって中断される可能性が高いため、CreateProcess(..)のバリエーションが大きくなります。時間計測には制御ループ全体が含まれているため(つまり、GetTickCount(..)が時間を計測するには不正確すぎるため)、スレッドを作成する時間はさらに短くなります。

Windows XPを実行している仮想PC上の別の試験(上記と同じマシン上で実行されている)は、次の値を生成:

--- CreateProcess(..) --- 
minimum execution time ...: 22.630ms 
average execution time ...: 24.666ms 
maximum execution time ...: 27.340ms 

--- CreateThread(..) --- 
minimum execution time ...: 0.076ms 
average execution time ...: 0.086ms 
maximum execution time ...: 0.100ms 


ratio: 287.982 

のCreateProcessの平均実行時間のInterrestingly比(..)とCreateThread(..)はかなり近いです。

他のマシンやバージョンのWindowsの値を確認するのが邪魔になります。異なるマシンやバージョンのWindowsで約300の比率がほぼ同じであれば、私は驚くことはありません。

結論:CreateProcess(..)は、Windows上でCreateThread(..)よりも遅いのです。しかし実際には、実際にどれほど遅くなっているのかはかなりわかりました...

+0

ニースの答え!あなたは、この2歳の質問に答えるためにバッジのいくつかの種類を稼ぐつもりです! – japreiss

関連する問題