Sometimes, when I run this simple program
#include <Windows.h>
DWORD WINAPI ThreadStart(LPVOID)
{
for (;;) { }
return 0;
}
int _tmain()
{
SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
SYSTEM_INFO si;
GetSystemInfo(&si);
for (DWORD i = si.dwNumberOfProcessors * 2; i > 0; i--)
{ CloseHandle(CreateThread(NULL, 0, &ThreadStart, NULL, 0, NULL)); }
Sleep(INFINITE);
}
I observe constantly unfair thread scheduling, such as:
It's not unfair on every run, but when it is, it stays unfair throughout the lifetime of the application.
Why does this happen, and what is the proper way to avoid it?
Thus software threads tend to evict each other's data, and the cache fighting from too many threads can hurt performance. A similar overhead, at a different level, is thrashing virtual memory. Most computers use virtual memory.
Windows implements a priority-driven, preemptive scheduling system—the highest-priority runnable (ready) thread always runs, with the caveat that the thread chosen to run might be limited by the processors on which the thread is allowed to run, a phenomenon called processor affinity.
There is nothing in the C++ standard that limits number of threads. However, OS will certainly have a hard limit. Having too many threads decreases the throughput of your application, so it's recommended that you use a thread pool.
A single CPU core can have up-to 2 threads per core. For example, if a CPU is dual core (i.e., 2 cores) it will have 4 threads. And if a CPU is Octal core (i.e., 8 core) it will have 16 threads and vice-versa.
Some options:
If (and only if) you're running Windows 7/8 64-bit (not 32-bit), or Windows Server 2008 R2 or later, you can bypass the system scheduler completely and take care of this yourself, although it's not a trivial undertaking!
It's described on MSDN here and is called User-Mode Scheduling (UMS).
Partial screenshot from MSDN below - is this any use for you?
In addition, it might be an idea to disable hyper-threading in your BIOS (if appropriate) because there is some debate as to how Windows distinguishes between logical and physical cores. See here for a discussion.
There are also a few functions available like SetThreadAffinityMask()
(MSDN here) and SetThreadIdealProcessor()
which may help although personally I've found this to be a bit hit-and-miss. It's more often the case that I harm overall throughput rather than help it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With