0

I have a multithreaded code that I want to run on all 4 cores that my processor has. I.e. I create four threads, and I want each of them to run on a separate core.

What happens is that it starts running on four cores, but occasionally would switch to only three cores. The only things running are the OS and my exe. This is somewhat disappointing, since it decreases performance by a quarter, which is significant enough for me.

The process affinity that I see in Task Manager allows the process to use any core. I tried restricting thread affinities, but it did't help. I also tried increasing priority of the process, but it did not help the case either.

So the question is, is there any way to force Windows to keep it running on all four cores? If this is not possible, can I reduce the frequency of these interruptions? Thanks!

2 Answers2

1

This is not an issue of affinity unless I am very much mistaken. Certainly the system will not restrict your process to affinity with a specific set of threads. Some other program in the system would have to do that, if indeed that is happening.

Much more likely however is that, simply, there is another thread that is ready to run that the system is scheduling in a round-robin fashion. You have four threads that are always ready to run. If there is another thread that is ready to run, it will get its turn. Now there are 5 threads sharing 4 processors. When the other thread is running, only 3 of yours are able to run.

If you want to be sure that such other threads won't run then you need to do one of the following:

  1. Stop running the other program that wants to use CPU resource.
  2. Make the relative thread priorities such that your threads always run in preference to the other thread.

Now, of these options, the first is to be preferred. If you prioritize your threads above others, then the other threads don't get to run at all. Is that really what you want to happen?

In the question you say that there are no other processes running. If that is the case, and nobody is meddling with processor affinity, and only a subset of your threads are executing, then the only conclusion is that not all of your threads are ready to run and have work to do. That might happen if you, for instance, join your threads at the end of one part of work, before continuing on to the next.

Perhaps the next step for you is to narrow things down a little. Use a tool like Process Explorer to diagnose which threads are actually running.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Thanks for your answer. Well, I should have probably stated it clearly that I personally don't care much about other processes -- there is my process and some system stuff that I need only as long as it is necessary for my process to run. Furthermore, my threads are simple for loops, and they are always "ready to run". Another issue is that they occasionally finish and I run a new batch, so this is probably when another process takes place. – Peter Kravchuk Apr 30 '14 at 10:42
  • If they are always ready to run, then the scheduler will run them. Are you joining your threads at any point? – David Heffernan Apr 30 '14 at 10:44
  • Well, I can guarantee that all 4 of my threads get executed, but on 3 cores. Yes, as I said, they occasionally finish their job, and I start a new set of 4 threads. It is quite probably the case that this is the point where it gets switched to 3 cores. I'll try to increase priorities again, but this so far only resulted in increasing priority on other cores. – Peter Kravchuk Apr 30 '14 at 10:47
  • I doubt that priorities will help. If there really are no other threads ready to run, why would the system not schedule one of yours that was ready to run? The only conclusion is that it is not ready to run. Typically that means it is blocking. – David Heffernan Apr 30 '14 at 10:50
  • May it be the case that the system prefers to give processor time on one core to some background system process? – Peter Kravchuk Apr 30 '14 at 10:53
  • You say that there is nothing else running on the system. If you want to work out what is happening, use some debugging tool. For instance Process Explorer. – David Heffernan Apr 30 '14 at 10:55
0

If this is windows, try SetThreadAffinityMask():

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686247(v=vs.85).aspx

I would assume that if you only set a single bit, then that forces the thread to run only on the selected processor (core).

other process / thread functions:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms684847(v=vs.85).aspx

I use a windows video program, and it's able to keep all the cores running at near max when rendering video.

rcgldr
  • 27,407
  • 3
  • 36
  • 61
  • Thanks for you answer. However, as I said I tried restricting thread affinities, and it didn't work. I think it is the process affinity which gets changed, thread affinities always respect process affinity. – Peter Kravchuk Apr 30 '14 at 10:49
  • Is this windows and did you use SetThreadAffinityMask() (you need one call from each thread) or did you attempt to do this with task manager? I've used that windows video program many times, and I've never seen it not using all the cores when rendering, so it is possible to prevent the threads from switching cores. – rcgldr Apr 30 '14 at 11:55
  • Yes, it is Windows and I used SetThreadAffinityMask() and I called it once for each of the threads. – Peter Kravchuk Apr 30 '14 at 18:16
  • So I assume that for each call from each thread you only had 1 bit set? If so that should have worked. I'm not sure how the video program avoids this problem when rendering. – rcgldr Apr 30 '14 at 23:25
  • @PeterKravchuk It seems to me that you are guessing that affinity is the issue. It is trivially easy to verify this. Don't guess. Check your affinities. You can read these easily from Process Explorer. Or you can check them in your program. Absolutely do not make your threads affinitised to just a single processor. That will damage your performance. Do not set any affinity in your code. Let the system schedule your threads. Only the system can see the whole picture. – David Heffernan May 01 '14 at 14:23