2012-05-22 4 views
11

Windows에서 새 프로세스를 만드는 데 비용이 많이 든다는 얘기를 계속 듣고 있습니다. 정확한 숫자를 찾을 수는 없습니다. 경기장의 야구장이 있습니까? 2GHz 듀얼 코어 프로세서에서 몇 밀리 초입니까?Windows에서 프로세스 생성 오버 헤드 란 무엇입니까?

파이썬에서 테스트 프로그램을 작성하고 프로세스 당 5ms를 측정했지만 파이썬의 추가 오버 헤드가 얼마나되는지 알지 못합니다. 나는별로 추측하지 않는다.

+0

요즘처럼주기가 CPU에서 같은 의미가 아닙니다. 스레드와 프로세스가 모두 커널 객체이기 때문에 적어도 하나의 커널 모드로 전환해야합니다. 그 외에도 Windows 버전 (Shims 고려)에 따라 달라집니다. – 0xC0000022L

+0

관련 토론 (답변이 아닙니다) : http://stackoverflow.com/questions/47845/why-is-creating-a-new-process-more-expensive-on-windows-than-linux – assylias

+0

Process Monitor (MS 웹 사이트에서 구할 수 있음)를 사용하고 새로운 프로세스 시작을 관찰함으로써이 규모의 아이디어를 얻을 수 있습니다. * 수천 개의 파일 및 레지스트리 작업이 발생합니다. –

답변

18

Interresting question!

앞서 언급 한 것처럼 오버 헤드가 높습니다. 호기심에서 스레드와 프로세스 생성에 걸리는 시간과 이러한 시간이 어떻게 관련되어 있는지 엄지 손가락을 얻기위한 작은 벤치 마크를 신속하게 작성했습니다.

#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에는, 윈도우 7) 몇 가지 실행을했습니다 및 안티 바이러스 응용 프로그램이 꺼져 있고 벤치 마크는 비주얼 스튜디오의 외부에서 시작되는 경우 값이 꽤 일치 :

--- 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 (..)가 시간을 측정하기에는 너무 정확하지 않을 수 있음).

윈도우 XP를 (상술 한 바와 같은 시스템에서 실행)를 실행하는 가상 PC에서 다른 테스트가 다음 값을 생성 : Interrestingly

--- 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를 (...)의 평균 실행 시간의 비율과 CreateThread (..) 꽤 가깝습니다.

다른 컴퓨터와 Windows 버전의 값을 보려면 인터 로킹해야합니다. Windows의 다른 컴퓨터와 버전에서 약 300의 비율이 거의 동일하다면 놀라지 않을 것입니다.

결론적으로 CreateProcess (..)는 Windows에서 CreateThread (..)보다 느린입니다. 입니다. 하지만 사실 실제로 얼마나 느린 지 꽤 충격적입니다 ...

+0

좋은 답변입니다!이 2 살짜리 질문에 대답하기 위해 어떤 종류의 배지를 얻을 것입니다! – japreiss