El otro día estaba investigando la posibilidad de ejecutar un Thread en un núcleo específico del procesador y me encontré con esta función de la API de Windows: SetThreadAffinityMask().
Se define así:
DWORD_PTR WINAPI SetThreadAffinityMask(__in HANDLE hThread, __in DWORD_PTR dwThreadAffinityMask);
Usando el siguiente programa y el taskmanager de Windows hice las siguientes pruebas:
#include <iostream>
#include <Windows.h>
using namespace std;
void threadFunc()
{
double a = 0;
for (unsigned long long i = 0;;i++)
{
a = (i * 17) - 32;
if (a > 0)
a = (sqrt(a) * 43) - 72;
}
}
int main(int argc, char * argv[])
{
SYSTEM_INFO sysInfo;
DWORD dwThreadId;
GetSystemInfo(&sysInfo);
cout << "Numero de nucleos: " << sysInfo.dwNumberOfProcessors << endl << endl;
BYTE coreToUse = 0; //Empieza en el 0
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadFunc, NULL, 0, &dwThreadId);
if (SetThreadAffinityMask(hThread, 1 << (coreToUse % 8)) != 0)
cout << "ThreadAffinity se establecio con exito en el nucleo " << (int)coreToUse << endl;
else
cout << "ThreadAffinity error! El sistema repartira la carga del Thread!" << endl;
cin.get();
return 0;
}
En la variable coreToUse especificas que núcleo que vas a usar para ejecutar el thread con la función threadFunc(). En mi caso tengo como procesador un AMD Athlon X 2 6400 - 3.2 GHz, por lo tanto sólo tiene 2 núcleos.
Como podéis ver en la imagen, el primer núcleo se pone al 100%.. Ahora voy a hacer lo mismo, pero poniendole el valor 1 a la variable coreToUse.
¿Qué pasaría si le pongo un valor mayor que 1? Pues en mi caso, como solo tiene 2 núcleos mi procesador, fallaría la función SetThreadAffinityMask() y por lo tanto el sistema repartiría la carga de la función threadFunc().
No trabajan los dos núcleos lo mismo, siempre va a trabajar más uno que otro, pero eso depende de los algoritmos de planificación del scheduler del kernel de Windows...
Y ahora viene la gran pregunta, ¿Vale la pena utilizar esta API? La verdad, yo no le encontré gran utilidad. Quizás con 2 núcleos no te sirva de mucho, pero con 8 o 12 núcleos se podrían hacer bastantes cosas a la vez. Supongo que para los videojuegos o programas que necesiten gran capacidad de cálculo les será útil. Aunque siempre dependes de la cantidad de núcleos que tenga el equipo que ejecute tu programa.
Saludos.