Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I would like to experiment with threads on a multi-core processor, e.g. to create a program that uses two different threads that are executed by two different processor cores.

However, it is not clear to me at which level the threads get allocated to the different cores. I can imagine the following scenarios (depending on operating system and programming language implementation):

  1. Thread allocation is managed by the operating system. Threads are created using OS system calls and, if the process happens to run on a multi-core processor, the OS automatically tries to allocate / schedule different threads on different cores.
  2. Thread allocation is managed by the programming language implementation. Allocating threads to different core requires special system calls, but the programming language standard thread libraries automatically handle this when I use the standard thread implementation for that language.
  3. Thread allocation must be programmed explicitly. In my program I have to write explicit code to detect how many cores are available and to allocate different threads to different core using, e.g., library functions.

To make the question more specific, imagine I have written my multi-threaded application in Java or C++ on Windows or Linux. Will my application magically see and use multiple cores when run on a multi-core processor (because everything is managed either by the operating system or by the standard thread library), or do I have to modify my code to be aware of the multiple cores?

share|improve this question

1 Answer 1

up vote 7 down vote accepted

Will my application magically see and use multiple cores when run on a multi-core processor (because everything is managed either by the operating system or by the standard thread library), or do I have to modify my code to be aware of the multiple cores?

Simple answer: Yes, it will usually be managed by the operating system or threading library.

The threading subsystem in the operating system will assign threads to processors on a priority basis (your option 1). In other words, when a thread has finished executing for its time allocation or blocks, the scheduler looks for the next highest priority thread and assigns that to the CPU. The details vary from operating system to operating system.

That said, options 2 (managed by programming language) and 3 (explicitly) exist. For example, the Tasks library and async/await in recent versions of .Net give the developer a much easier way to write parallelizable (i.e. that can run concurrently with itself) code. Functional programming languages are innately parallelizable and some runtimes will run different parts of the program in parallel if possible.

As for option 3 (explicitly), Windows allows you to set the thread affinity (specifying which processors a thread can run on). However, this is usually unnecessary in all but the fastest, response-time critical systems. Effective thread to processor allocation is highly hardware dependent and is very sensitive to other applications running concurrently.

If you want to experiment, create a long running, CPU intensive task like generating a list of prime numbers or creating a Mandelbrot set. Now create two threads in your favorite library and run both threads on a multi-processor machine (in other words, just about anything released in the last few years). Both tasks should complete in roughly the same time because they are run in parallel.

share|improve this answer
    
Thanks for the explanation (+1). My test program is a merge sort implementation. In the split phase, I want to create different threads as long as there are cores available. E.g., with two cores, each half of an array would get sorted by a different thread / core. During merge the superfluous threads would then be joined / terminated. –  Giorgio Jan 1 '13 at 12:07
    
Sorting is tough to parallelize in this way if the data is distributed randomly. Yes, you can break it up then sort each portion in a different thread but you eventually have to merge all the portions together, anyway. If the threads are sharing data structures, you may also get contention or locking issues. I am not saying sorting cannot benefit from threading but it will not be a linear performance improvement. –  akton Jan 1 '13 at 13:56
    
The two halves of an array can be sorted independently because no data is shared. Only the first split and the last merge will have to be performed by one thread manipulating the whole array or list containing the data. This means that one complete scan of the data cannot be executed in parallel; all remaining scans can. –  Giorgio Jan 1 '13 at 13:59
    
Of course, I also consider your examples as good candidates. I am just more familiar with merge sort at the moment (and I have implemented a non-parallel version of it), which would (maybe) make merge sort more suitable for me as a first attempt. –  Giorgio Jan 1 '13 at 14:02
1  
I would add to this answer that good operating systems are smart enough to balance the cost of giving a task a time slice on a different CPU or core with that of short-term starvation. On architectures where it matters, the result tends to resemble automagic affinity. The OS has been built around getting all jobs run as quickly as possible, and you may be shooting yourself in the foot by tying threads to cores and hamstringing its ability to make those decisions. –  Blrfl Jan 1 '13 at 14:07

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.