30

I have a Pentium core i5 processor, which has 4 cores. If I do this in a C# console program

var t1 = new Thread(Thread1);
var t2 = new Thread(Thread2);
t1.Start();
t2.Start();

are t1 and t2 threads guaranteed to run on separate cores?

Oliver Salzburg
  • 86,445
  • 63
  • 260
  • 306
developer747
  • 424
  • 1
  • 4
  • 9
  • 1
    Assuming that the C# runtime uses equivalent native system calls to spawn another thread (and is thus truly parallel; this is not the case for everything, like CPython's infamous [Global Interpreter Lock](http://en.wikipedia.org/wiki/Global_Interpreter_Lock)), this would depend solely on the operating system's [process/task scheduler](https://en.wikipedia.org/wiki/Scheduling_%28computing%29). In general though, code is truly thread safe if you assume that `t1` and `t2` are executed at different times in an arbitrary order (e.g. it's possible `t2` starts *before* `t1` in some models). – Breakthrough Jun 07 '13 at 20:45
  • 2
    I didn't know that there were Pentium i5 processors. Maybe you meant Core i5? Picky. I know :D – JosephGarrone Jun 08 '13 at 01:59

2 Answers2

20

You cannot guarantee in .Net that two Threads run on two separate cores. In fact, you also cannot guarantee that one Thread will run on only one core(!).

This is because managed threads are not the same as OS threads - a single managed Thread may use multiple OS threads to support it. In C#, you only ever deal directly with managed Threads (at least, without resorting to p/invoke to call the WinAPI threading functions, which you should never do).

However, the .Net and Windows thread schedulers are very good at what they do - they wouldn't run two threads on a single core while a second core sits completely idle. So, in general, you don't need to worry about it.

  • In practice, .Net `Thread`s *are* OS threads. But that's not why there is no guarantee that a single thread will always execute on the same core. – svick Jun 07 '13 at 21:44
  • 2
    @svick: In practice, **on x86**, that is true. However, the standard explicitly states that you cannot rely on this behavior, so it could change in the future. In fact, it is *not* true on other versions of the .Net CLR, like XBox 360's. – BlueRaja - Danny Pflughoeft Jun 08 '13 at 18:39
  • @BlueRaja - The question is specific about what version of the CLR we are talking about. You can guarantee something will exists on two seperate cores by using async threads because it would mean they would happen async from one another. The current example code is a sync call technically. Of course the operating system decides what cores would be used. – Ramhound Aug 06 '13 at 16:45
  • @Ramhound *"You can guarantee something will exists on two seperate cores by using async threads"* - that is false. The `async` keyword *(which is what I assume you are talking about, as "async threads" is redundant)* is just syntactical sugar for using a `BackgroundWorker` thread, which is like any other .Net thread - you can't guarantee whether it will run on a separate core or not. – BlueRaja - Danny Pflughoeft Aug 06 '13 at 17:56
  • @BlueRaja - If two async threads were started they would both run at the same time provided there were 2 CPU cores. If there was only one then the operating system would schedule when each thread would get priority and run and your typical single threaded thrashing situation would happen. This was how I was taught how a CPU handels multi-threads. – Ramhound Aug 06 '13 at 18:04
  • @Ramhound: Your understanding is close, but flawed. Even if the computer has two cores, the OS won't *necessarily* schedule both threads to separate cores *(eg. it might currently be using one of the cores for something much higher priority)*. In that case, both threads would be scheduled to the same core, and the usual context-switching would occur *(which would have to occur anyways; a normal PC has dozens of processes running at once!)*. Also, it's not called 'thrashing' - that is something [completely different](http://en.wikipedia.org/wiki/Thrashing_%28computer_science%29). – BlueRaja - Danny Pflughoeft Aug 06 '13 at 18:10
  • @BlueRaja - You are indeed right Thrashing is something else, the specific term I am looking for, currently escapes me. I suppose two async threads could be given the same core, finding it hard to find the words, to describe exactly what I am thinking of so I will just drop it. – Ramhound Aug 06 '13 at 18:32
17

No, the OS and CPU will decide what to run and when. in the simple example you have shown, to the exclusion of other tasks, yes those would most likely run in parallel on separate cores, but there is rarely a guarantee that that will be the case.

You can use the thread affinity to attempt to take some control over the allocation of a core to a given thread.

Also consider scheduling priorities to stack the deck in terms of which threads should be entirely parallel, and which can wait.

svick
  • 927
  • 1
  • 8
  • 26
Frank Thomas
  • 35,097
  • 3
  • 77
  • 98
  • 1
    I also want to add, that with virtualization technologies there is another layer between your program and the hardware. What the OS presents to the application might not be physically accurate. – Keltari Jun 07 '13 at 19:07
  • 1
    Those are WinAPI functions for OS threads, not for managed threads. They should never be called from C#, as they could severely interfere with the .Net thread scheduler. – BlueRaja - Danny Pflughoeft Jun 07 '13 at 20:31