Trên hệ thống của tôi, SetThreadAffinityMask
dường như giảm thiểu vấn đề. Vẫn còn một số sự mất cân bằng, rõ ràng là do một lõi có ít thời gian hơn so với người khác, nhưng nó không nghiêm trọng.
Windows dường như không muốn di chuyển các chủ đề này giữa các lõi; họ hiếm khi thay đổi lõi sau giây đầu tiên.Nếu các luồng không phân bố đều giữa các lõi, thời gian của luồng sẽ phản ánh điều đó.
Đây là mã tôi đã sử dụng để thử mặt nạ ái lực:
#include <Windows.h>
#include <stdio.h>
DWORD WINAPI ThreadStart(LPVOID arg)
{
DWORD pn1, pn2;
printf("Thread %u on processor %u\n", GetThreadId(GetCurrentThread()), pn1 = GetCurrentProcessorNumber());
// The problem comes back if you enable this line
// SetThreadAffinityMask(GetCurrentThread(), -1);
for (;;)
{
for (int i = 0; i < 10000; i++);
pn2 = GetCurrentProcessorNumber();
if (pn2 != pn1)
{
pn1 = pn2;
printf("Thread %u on processor %u\n", GetThreadId(GetCurrentThread()), pn1);
}
}
return 0;
}
int main(int argc, char ** argv)
{
SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
SYSTEM_INFO si;
GetSystemInfo(&si);
for (DWORD i = 0; i < si.dwNumberOfProcessors; i++)
{
SetThreadAffinityMask(CreateThread(NULL, 0, &ThreadStart, NULL, 0, NULL), 1 << i);
SetThreadAffinityMask(CreateThread(NULL, 0, &ThreadStart, NULL, 0, NULL), 1 << i);
}
Sleep(INFINITE);
return 0;
}
Cách tiếp cận này cũng dường như để giảm thiểu vấn đề này, mặc dù có lẽ không phải là một cách hiệu quả:
#include <Windows.h>
#include <stdio.h>
DWORD WINAPI ThreadStart(LPVOID arg)
{
for (;;);
return 0;
}
int main(int argc, char ** argv)
{
SYSTEM_INFO si;
GetSystemInfo(&si);
for (DWORD i = si.dwNumberOfProcessors * 2; i > 0; i--)
{
CreateThread(NULL, 0, &ThreadStart, NULL, 0, NULL);
}
for (;;)
{
SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
Sleep(100);
SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
}
return 0;
}
Tôi nghi ngờ rằng chúng tôi xem xét lại một số biện pháp tiết kiệm năng lượng được thiết kế dựa trên giả định rằng các luồng có mức độ ưu tiên thấp không cần lập lịch biểu công bằng. (Có thể cho rằng, đặt một luồng hoặc quy trình thành mức độ ưu tiên thấp cho biết "Tôi không quan tâm tôi nhận được bao nhiêu CPU.")
Bạn có chế độ CPU nào? Nó thực sự là một lõi tứ, hay là lõi kép với siêu phân luồng? – selbie
Ngoài ra, phiên bản Windows nào. Đó cũng là điều quan trọng cần biết. – selbie
@selbie: HT 2 lõi (Core i5, là máy tính xách tay), Windows 8 x64. – Mehrdad