Programming Multi Core Processors

It is not any harder to code for parallel processors, the same exact code will work on all X86 processors in existance [provided OS support]. It is harder to code well, however, because to get the maximum possible performance, you are necissitated to use multiple threads, and have a good scheme for inter-thread communication [Windows messages in all likelyhood].

Of course, threading by itself doesn't mean all your processors will be used to max, because if the tasks are not Parallel, you still have once processor waiting on another. And people still tend to think sequentially during a program design [Do A, then B, wait for response, do C, etc], so there is limited oppertunity to parallelize threads well.
 

Houndsteeth

Distinguished
Jul 14, 2006
514
3
19,015
Multi-thread programming becomes problematic because of this; thread A starts with dataset A and begins processing. Along the way, it takes values from the dataset and changes them, writing them back to the dataset. Being a well designed thread, it locks that data in place while it is reading it, and then locks it again when it is writing the calculated value back. These are known as operation locks (oplocks for short). Now, thread B comes along and is reading fromt he same dataset. Since thread A and thread B are working from the same data, they now have to contend with each other since one or another is locking the dataset continuously. In well-designed operating systems, there is a controller who keeps these kids in line, much like the father who tells the kids in the back seat to cool it on a long road trip. To add to this, when thread A is done with it's work, it's got all kinds of loose end laying all around, ready to trip up any other thread that has to work in the same space. So, a well-designed program goes through and cleans up this garbage (coincidentally, this action is known as "garbage collection") so other threads can work without interruption.

To add to this, a programmer has to know at which point it is good to spawn new threads. In some operating systems, thread creation is an expensive process with regards to resources, since some operating systems have very rigorous thread management. Others let their threads run wild, as long as they don't disturb the parents (ie, the operating system). BSOD in Windows? Probably a thread that got out of hand. Unimplemented trap in OS X? Yep, a thread that zigged when it should have zagged.

Now, I won't go more into race conditions and oplocks here, but these factor into multi-threading heavily, especially when the codebase you are working in doesn't give you nice tools to manage these resources (ahem, C...you have to be very much on your game when mutli-threading in C), while others throw everything at you (Java, .NET) and yet others make it look like child's play (Obj-C with GCD).
 

wizardprang

Distinguished
Jun 10, 2010
39
0
18,530
Single-core programming means thinking in terms of programs. They start, they run, then end.

Multi-core programming means thinking in threads -- small self-contained pieces of code that can run independently of each other.
 
Being a well designed thread, it locks that data in place while it is reading it, and then locks it again when it is writing the calculated value back

No, no, no!!! This is INCORRECT!

It is necessary to lock data during reads/writes ONLY in the circumstance that some other thread has the oppertunity to change the value you are currently using at the same time. If no other thread has the oppertunity to read/write that data, there is no need to waste CPU resources putting a lock on it.

BSOD in Windows? Probably a thread that got out of hand.

More like memory corruption, which has nothing to do with thread management.

To add to this, when thread A is done with it's work, it's got all kinds of loose end laying all around, ready to trip up any other thread that has to work in the same space.

Nope. In Windows, every piece of data a process uses exists within the same Virtual Memory space [2GB for Win32, up to 192GB (software limit) in Win64]. What one thread does to some piece of data will have no impact on the rest of hte process unless:
A: You run out of Virtual Memory [and thus need to clean up some space]
B: Another thread tries to use it

ahem, C...you have to be very much on your game when mutli-threading in C

Technically, C only supports p-threads, which are designed for cooroporative multithreading, which is no longer supported by any major OS. All threading is typically done using the OS [Windows] API, and not the language itself. [Though the latest C/C++ revisions are finally adding proper multi-threading support...]

I've written programs in C (not even C++) that manage dozens (40+) threads without any issues. Its not that hard, assuming your program design is correct. [I find most problems with threading is the programmer trying to apply threading incorrectly]

Single-core programming means thinking in terms of programs. They start, they run, then end.

Wrong. For my college seminar project, I wrote a program that scaled dynamically to 40 or so threads. This was back in the late 90's, running happily on a 1.2GHz Pentium III.

A thread is the basis of execution in windows. Regardless of single/multiple cores, within Windows, the thread with the highest priority always runs. When you adjust priority of a process in task manager, all you do is increment the priority of that process' threads, nothing more.

A good reason to thread on a single core system is to prevent the user input from locking up during a long operation. For example, your encoding a video and decide you want to stop, so you hit the "cancel" button. If you didn't make the actual encoding operation [which continues until done or an error detected] seperate from the GUI, the mouse click on cancel event would never get parsed, and the user input would not do anything. [As a general rule, if writing a GUI application that does any significant work, make the default thread that starts up the GUI thread, and make new threads for any other work not involving the GUI].
 

aadv

Distinguished
May 11, 2011
1
0
18,510


It is harder because you learned programming with imperative programming languages that are inherently sequential.

Let me illustrate this with a simple example in Java. Assume you want to increment both x and y. The two variables are totally independent and unrelated, but you *have* to write your code in a sequential way, namely you have to decide which one is first and which one is second, just because Java does not have any other way to combine statements.

So you'll end up writing either [cpp]{ x++; y++; }[/cpp] or [cpp]{ y++; x++; }[/cpp] although you don't care about the order. Now, if you want to run things in parallel, you (or some programming tool) will have to uncover what could be the potential parallelism in this apparently sequential code.

In contrast, if you use a language that can express the parallel combination of statements, such as Ateji PX (http://www.ateji.com/px), you'll write code without having to decide which statement should be first. This is expressed as [cpp][ x++; || y++; ][/cpp] (the parallel bar || composes statements in parallel). This parallel block will run either x++ or y++ first, you cannot predict which one - and you don't care, so this is the behaviour you want.

Adding threads to a sequential language raises a stream of problems. My guess is that, should you have learned programming with such a language, or a purely functional or logic language where parallelism is implicit and there are no side effects, then you would find parallel programming natural, not hard.
 
^^ Yeah, programming languages are an inherent bottleneck. Using threads helps, but all that does is simply parallizes down to the thread level, and not per-instruction parallization.

APL is actually a good language for parallel operations, but heaven forbid the syntax...