Windows 中的进程创建开销是多少? [英] What is the process creation overhead in Windows?

查看:145
本文介绍了Windows 中的进程创建开销是多少?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直听说在 Windows 中创建一个新进程非常昂贵.但我找不到确切的数字.是否有一个大概的周期数?2GHz 双核处理器需要多少毫秒?

I keep hearing that it's very expensive to create a new process in Windows. But I can't find exact numbers. Is there a ballpark number of cycles? How many milliseconds on a 2GHz dual-core processor?

我用 Python 编写了一个测试程序并测量了每个进程 5 毫秒,但我不知道其中有多少是 Python 的额外开销.我猜不会太多.

I wrote a test program in Python and measured 5ms per process, but I don't know how much of that is extra overhead from Python. I'm guessing not much.

推荐答案

有趣的问题!

如前所述,开销很高.出于好奇,如果您快速编写了一个小基准来获得一些经验,线程和进程的创建需要多长时间以及这些时间是如何相关的.

As said before the overhead is high. Out of curiosity if've quickly written a little benchmark to get a number of thumb how long the creation of a thread and a process takes and how these times are related.

#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 外部启动基准测试,则这些值非常一致:

I've made several runs on my computer (i5 3.2GHz; Windows 7) and the values are pretty consistent if the anti virus application is turned off and the benchmark is started from outside of 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(..) 测量时间会太不准确).

As expected the variation of CreateProcess(..) is bigger since more system calls are involved and the likelyhood of being interrupted by another thread is higher. Remember that the time to create the thread is even shorter since the time measurement includes the whole control-loop (otherwise GetTickCount(..) would be too inaccurate to measure the time).

在运行 Windows XP(在上述同一台机器上运行)的虚拟 PC 上进行的另一项测试产生了以下值:

Another test on a virtual PC running Windows XP (running on the same machine as mentioned above) produced the following values:

--- 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(..) 的平均执行时间的比率非常接近.

Interrestingly the ratio of the average execution times of CreateProcess(..) and CreateThread(..) are pretty close.

查看其他机器和 Windows 版本的值会很有趣.如果在不同的机器和版本的 Windows 上大约 300 的比率大致相同,我不会感到惊讶.

It would be interresting to see values of other machines and versions of Windows. I would not be surprised if a ratio of about 300 is about the same on different machines and versions of Windows.

让我们得出结论:CreateProcess(..) 比 Windows 上的 CreateThread(..) 慢得多.但实际上我很震惊它真的慢了多少......

So let's conclude: CreateProcess(..) is much slower than CreateThread(..) on Windows. But actually I'm quite shocked how much slower it really is...

这篇关于Windows 中的进程创建开销是多少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆