Câu hỏi liên tiếp!
Như đã nói trước khi phí trên cao. Ngoài sự tò mò nếu đã nhanh chóng viết một chút điểm chuẩn để có được một số ngón tay cái bao lâu việc tạo ra một sợi và một quá trình mất và làm thế nào những lần này có liên quan.
#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);
}
Tôi đã thực hiện một số chạy trên máy tính của tôi (i5 3.2GHz; Windows 7) và các giá trị là khá phù hợp nếu ứng dụng chống virus được tắt và điểm chuẩn được bắt đầu từ bên ngoài của 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
Như mong đợi, biến thể của CreateProcess (..) lớn hơn do có nhiều cuộc gọi hệ thống hơn và khả năng bị gián đoạn bởi chuỗi khác cao hơn. Hãy nhớ rằng thời gian để tạo ra các sợi thậm chí còn ngắn hơn kể từ khi đo thời gian bao gồm toàn bộ vòng lặp điều khiển (nếu không GetTickCount (..) sẽ là quá không chính xác để đo thời gian).
Một thử nghiệm trên một máy tính ảo chạy Windows XP (chạy trên cùng một máy như đã đề cập ở trên) sản xuất các giá trị sau:
--- 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
Interrestingly tỷ số giữa thời gian thực hiện trung bình của CreateProcess (..) và CreateThread (..) khá gần.
Nó sẽ là sự can thiệp để xem giá trị của các máy và phiên bản Windows khác. Tôi sẽ không ngạc nhiên nếu một tỷ lệ khoảng 300 là về cùng trên các máy khác nhau và các phiên bản của Windows.
Vì vậy, hãy kết luận: CreateProcess (..) là nhiều hơn chậm hơn CreateThread (..) trên Windows. Nhưng thực sự tôi khá sốc vì nó thực sự chậm hơn bao nhiêu ...
Chu kỳ không có ý nghĩa tương tự đối với CPU những ngày này như trước đây. Bạn sẽ có ít nhất một chuyển đổi vào chế độ hạt nhân, vì cả hai luồng và các tiến trình đều là các đối tượng hạt nhân. Ngoài ra nó cũng sẽ phụ thuộc vào phiên bản Windows (xem xét Shims). – 0xC0000022L
Thảo luận liên quan (nhưng không phải là câu trả lời): http://stackoverflow.com/questions/47845/why-is-creating-a-new-process-more-expensive-on-windows-than-linux – assylias
Bạn có thể nhận được ý tưởng về quy mô này bằng cách sử dụng Process Monitor (có sẵn từ trang web MS) và xem một quá trình mới khởi động. Có * hàng ngàn * tập tin và các hoạt động đăng ký diễn ra. –