first, you need to know how many processors/cores are available to you.
this is done with the GetNumCPUs() function.
DWORD_PTR GetNumCPUs() {
SYSTEM_INFO m_si = {0, };
GetSystemInfo(&m_si);
return (DWORD_PTR)m_si.dwNumberOfProcessors;
}
this pretty much returns the number of available cores (note: single cpu's that are hyperthreading enabled also show as 2 cpu's).
once you have the number of processor, you can then create a loop that will cycle through each processor.
DWORD_PTR c = GetNumCPUs();
for(DWORD_PTR i = 0; i < c; i++) {
}
this will simply cycle through a for loop at least once (because you will always have 1 processor) upto the number of processors/cores you have.
now, if you want to actualy DO something with this loop and your processors/cores, you will need to create some threads for them. each thread will run independantly of the others within the application (though, they can interact, this is not the purpous of this tutorial).
first you will need to create your thread procedure.
DWORD_PTR WINAPI threadMain(void* p) {
return 0;
}
this is a simple "do nothing" thread that you can fill in later.
next, you will need to create the threads.
m_threads = new HANDLE[c]; //needed to store the handles of your threads
DWORD_PTR c = GetNumCPUs();
for(DWORD_PTR i = 0; i < c; i++) {
DWORD_PTR m_id = 0; //mostly useless, just to complete the CreateThread function
//create the thread and store its handle for later, and pass the processor count to the thread
m_threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadMain, (LPVOID)i, NULL, &m_id);
}
now you have a thread running for each cpu within the current system (ie, on mine it would be 2, on a quad core, it would be 4, on a single core system, it would be 1), but we havnt assigned them to any particular cpu or core yet. the processor its self, and the operating system will generaly do this for you automaticaly, but wont split them up equaly, they will just offload them to the processors/cores that are least being utalized at the time.
so now, we will assign the threads to each processor/core our selfs.
m_threads = new HANDLE[c]; //needed to store the handles of your threads
DWORD_PTR c = GetNumCPUs();
for(DWORD_PTR i = 0; i < c; i++) {
DWORD_PTR m_id = 0; //mostly useless, just to complete the CreateThread function
DWORD_PTR m_mask = 1 << i; //creates a mask of the processor/core number
//create the thread and store its handle for later, and pass the processor count to the thread
m_threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadMain, (LPVOID)i, NULL, &m_id);
SetThreadAffinityMask(m_threads[i], m_mask); //assigns the thread to a processor/core
wprintf(L"Creating Thread %d (0x%08x) Assigning to CPU 0x%08x\r\n", i, (LONG_PTR)m_threads[i], m_mask); //just so we can see whats going on as it goes on (if your not using unicode, you should use printf here and not wprintf.
}
and thats it, put it together, and you have an application that can be far more effective at doing almost anything as long as you know what your doing.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
HANDLE *m_threads = NULL;
DWORD_PTR WINAPI threadMain(void* p);
DWORD_PTR GetNumCPUs() {
SYSTEM_INFO m_si = {0, };
GetSystemInfo(&m_si);
return (DWORD_PTR)m_si.dwNumberOfProcessors;
}
int wmain(int argc, wchar_t **args) {
DWORD_PTR c = GetNumCPUs();
m_threads = new HANDLE[c];
for(DWORD_PTR i = 0; i < c; i++) {
DWORD_PTR m_id = 0;
DWORD_PTR m_mask = 1 << i;
m_threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadMain, (LPVOID)i, NULL, &m_id);
SetThreadAffinityMask(m_threads[i], m_mask);
wprintf(L"Creating Thread %d (0x%08x) Assigning to CPU 0x%08x\r\n", i, (LONG_PTR)m_threads[i], m_mask);
}
return 0;
}
DWORD_PTR WINAPI threadMain(void* p) {
return 0;
}
Research: CreateThread | SetThreadAffinityMask | GetSystemInfo






MultiQuote




|