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.

Recently I have often read that, since the trend is to build processors with multiple cores, it will be increasingly important to have programming languages that support concurrent and parallel programming in order to better exploit the parallelism offered by these processors (see e.g. this video for some background.).

In this respect, certain programming paradigms or models are considered well-suited for writing robust concurrent software:

  • Functional programming languages, e.g. Haskell, Scala, etc.
  • The actor model: Erlang, but also available for Scala / Java (Akka), C++ (Theron, Casablanca, ...), and other programming languages.

My questions:

  • What is the state of the art regarding the development of concurrent applications (e.g. using multi-threading) using the above languages / models? Is this area still being explored or are there well-established practices already?
  • Will it be more complex to program applications with a higher level of concurrency, or is it just a matter of learning new paradigms and practices?
  • How does the performance of highly concurrent software compare to the performance of more traditional software when executed on multiple core processors?
  • For example, has anyone implemented a desktop application using C++ / Theron, or Java / Akka? Was there a boost in performance on a multiple core processor due to higher parallelism?

EDIT

NOTE that I am not asking for your opinions or for debate but for concrete experiences or information. For example, has anyone written a Scala or Haskell program, compiled it with existing state-of-the-art compilers, and

  1. Run it on an Intel Core i3 and measured a certain performance (e.g. 10 seconds on certain input data).
  2. Run the same bytecode or binary on an Intel Core i5 and observed a performance boost (e.g. 6 seconds running time) due to the parallel computation of sub-expressions which is possible in functional code?

EDIT 2

SUMMARIZING. Up to now making faster processors meant increasing the clock speed, and no changes in programming paradigm were needed. In the last few years making faster processor has meant adding more cores but this requires we write software differently. My question is whether software developers are starting to switch to new programming paradigms and whether this is bringing the expected performance boost on multiple-core processors.

share|improve this question

closed as not constructive by Jarrod Roberson, ChrisF Jul 8 '12 at 18:46

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.If this question can be reworded to fit the rules in the help center, please edit the question.

1  
concurrency is a very generic topic in the programming world, basically this word mean "more than one process accessing the same resource at the same time", it's a common problem in the SQL world for example, probably you better specify that you are just talking about multi-threaded applications. –  user827992 Jul 7 '12 at 23:00
    
My point is that up to now we had a constant increase in software speed because processor clocks increased. From now on the performance increase is expected to come from the use of multiple core processors. The point: is this realistic? Will we start to simply use multi-threading systematically to exploit all the processing power? –  Giorgio Jul 7 '12 at 23:03
    
I had not written multi-threading explicitly because I guess one can also obtain a performance increase by splitting an application into multiple processes, e.g. a word processor could have a background process taking care of printing. –  Giorgio Jul 7 '12 at 23:06
    
i get your point and for this reason i'm suggesting you to make this change; anyway i think that the registers of the modern CPUs can give very good performance in both cases, there is a gain in terms of perfomance but your code will be less portable and less readable, you can use solutions such as OpenMP or Intel Threading Building Blocks, OpenMP is better for re-using existing code and the library from Intel is probably better suited for abstraction. If you really want to gain performance and have a real step up use OpenCL. –  user827992 Jul 7 '12 at 23:10
    
there is also a consideration, in the end CPUs are not really maded with parallel computing in mind so you can always find a real bottleneck in your architecture, technologies like OpenCL are born from parallelization. –  user827992 Jul 7 '12 at 23:12

2 Answers 2

(This is not a full answer, but it seems too long to fit in a comment.)

There are many factors affecting the adoption rate of "Design for parallelism" in the software industry. Some of them had nothing to do with the benefits. For example, the skill sets and knowledge levels of developers, etc.

One of my observation is that the type of application determines its adoption rate of parallel paradigm. Each software product line (level) or component has one or more "natural domain / paradigm"; that is, the software would be much easier to develop and maintain if it was implemented in a particular paradigm.

If a paradigm switch is necessary in order to parallelize a certain application, chances are that software companies won't find that cost-effective to justify. If that particular paradigm is easily parallelizable, then what you see is that those software would have higher adoption rate for parallel programming.


Regarding the list of paradigms, I would like to add Dataflow. All tasks are declared up-front. Each task declares its inputs and outputs before execution. A task is started as soon as all of its input data is available.

Examples of Dataflow paradigm:


Answer 1:

Having one very successful paradigm is not enough. To bring up adoption rate of parallel programming, parallelism need to be introduced to other paradigms (including the "outdated" ones) as well.

I have seen others who successfully implemented parallelism in a Windows GUI program, by spawning one Windows dialog (each Windows dialog is housed in a thread) per computation task, and exchange data using Windows messages.


Answer 2:

This echoes my observation above: if the introduction of parallelism into an application requires that application to be rewritten in an unnatural paradigm, then the complexity of development and maintenance will be increased.


Answer 3:

For purely computationally-intensive tasks, the performance gain usually matches very closely with the prediction by Amdahl's Law, provided that all of the computation is done locally on a computer (i.e. not subject to the much slower network I/O traffic.)

That said, you will quickly find out there are non-parallelizable bottlenecks in your applications. Sometimes these bottlenecks are theoretically non-parallelizable, meaning there is no hope of finding a better algorithm.


Answer 4:

A personal story. I have written a simple parallelized program that decodes a JPEG file, resize it, and then save it into a custom image file format. Upon testing, I find that the program takes 1.6 seconds to finish, when tested using 3 threads or 4 threads. It turns out the JPEG decoding step is taking more than 25% of the time, making it the slowest non-parallelizable step.

In other words, Amdahl's law takes effect with just 3-4 CPU cores for my little program.

Sometimes these bottlenecks can be removed if you are allowed to change the software requirements (for example, if you could require your customers to not use a particular image format), but most of the time the requirements are set in stone.

share|improve this answer
    
Thanks for the very detailed answer. But I was not thinking about programming multiple threads explicitly, but rather about languages (like functional languages) or models (like the actor model) in which multi-threading is managed automatically by the compiler or the runtime environment. E.g., in the actor model, each small object can potentially be run in a separate thread. The programmer does not see how the runtime allocates objects to threads (and to processor cores). –  Giorgio Jul 8 '12 at 8:44
    
You still need to hint to the system how your program consists of small chunks –  user1249 Jul 8 '12 at 9:05
    
@Thorbjørn Ravn Andersen: In a functional language, any expression f(g(x), h(y)) where g and h are pure functions can be automatically parallelized by the compiler by computing g(x) and h(y) on different threads (I guess it is then the OS who decides whether these threads get allocated to different processor cores). –  Giorgio Jul 8 '12 at 9:16
    
@Giorgio sure, but are those chunks small enough. Have a look at Haskell - they've done quite a lot of work there. –  user1249 Jul 8 '12 at 9:25
    
@Thorbjørn Ravn Andersen: "but are those chunks small enough." I am not sure I understand what you mean. I imagine that in Haskell the computation is split into smaller, parallel chunks automatically. As far as I understand, the programmer just has to write a Haskell program (and try do use pure functions as much as possible), and the compiler will take care of parallelising the computation. –  Giorgio Jul 8 '12 at 9:45

You cannot magically make code not written for concurrency work well concurrently (and magically includes using compilers).

Many times conditions have changed and code needed to be done differently. In the very old days, memory was a premium, so self-modifying code was common. These days, the benefits of code in memory being read-only are so great that all modern operating systems want to enforce it.

Also think what happened when Windows became popular. All the DOS programmers had to rethink their programming ways. You could not have a single keyboard polling loop invoking the complete application functionality in a single threaded program - you had to have event handlers - which in turn changed the way the application code was designed.

Mantras like "use immutable objects!" are experiences learned the hard way. The reasons why are frequently lost on the way but can be reconstructed. The "use immutable objects" is a simple way to allow caching data multiple places without having your program break by one of these places being updated.

The change needed to be concurrent does not need to be a full rewrite in a functional language, but can be solved with libraries - which allows to keep existing code libraries - but you still need to write your program to utilize it. The OpenCL (Grand Central in OS X) approach is a very interesting way to use both CPU and GPU's to execute code, but again you need to make your program accordingly.

In Java a lot of effort has been spent on providing good building blocks for transparently scale the executing of small code snippets, but you cannot use it if you do not write for it.

share|improve this answer

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