Sul mio sistema, SetThreadAffinityMask
sembra attenuare il problema. C'è ancora uno squilibrio, apparentemente a causa di un nucleo che ha meno tempo a disposizione rispetto all'altro, ma non è così grave.
Windows sembra non voler spostare questi fili tra i core; raramente cambiano core dopo il primo secondo circa.Se i thread non sono equamente distribuiti tra i core, i tempi di thread lo riflettono.
Questo è il codice che ho usato per provare le maschere di affinità:
#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;
}
Questo approccio sembra anche di mitigare il problema, anche se forse non nel modo più efficace:
#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;
}
Ho il sospetto che noi' stiamo guardando ad una qualche misura di risparmio energetico progettata partendo dal presupposto che i thread a bassa priorità non abbiano bisogno di una programmazione equa. (Probabilmente, impostare un thread o un processo su bassa priorità dice "Non mi interessa quanta CPU ottengo.")
Che tipo di CPU hai? In realtà è un quad-core o dual-core con hyperthreading? – selbie
Inoltre, quale versione di Windows. Anche questo è importante sapere. – selbie
@selbie: 2-core HT (Core i5, è un laptop), Windows 8 x64. – Mehrdad