Wydaje się, że w moim systemie problem jest łagodzony przez SetThreadAffinityMask
. Nadal istnieje pewien brak równowagi, najwyraźniej ze względu na to, że jeden rdzeń ma mniej czasu wolnego niż drugi, ale nie jest tak poważny.
Windows wydaje się niechętny do przesuwania tych wątków między rdzeniami; rzadko zmieniają rdzeń po pierwszej sekundzie.Jeśli nici nie są równomiernie rozmieszczone między rdzeniami, to czasy nitek odzwierciedlają to.
Jest to kod użyłem do wypróbowania masek powinowactwa:
#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;
}
Takie podejście wydaje się również, aby złagodzić ten problem, choć może nie tak skutecznie:
#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;
}
podejrzewam, że my” ponowne spojrzenie na jakiś środek oszczędzania energii zaprojektowany przy założeniu, że wątki o niskim priorytecie nie wymagają sprawiedliwego planowania. (Prawdopodobnie ustawienie wątku lub procesu o niskim priorytecie mówi "Nie obchodzi mnie, ile mam CPU.")
Jaki masz tryb procesora? Czy to w rzeczywistości czterordzeniowy, czy też dwurdzeniowy z hyperthreading? – selbie
Również, jaka wersja systemu Windows. Ważne jest również, aby wiedzieć. – selbie
@selbie: 2-rdzeniowy HT (Core i5, to laptop), Windows 8 x64. – Mehrdad