Nov
12

Two Paths to Concurrency – Comparing Erlang and LabVIEW

by Tomi Maila, Nov 12, 2007 at 11:46 pm
1 Star2 Stars3 Stars4 Stars5 Stars (5 votes, average: 4.60 out of 5)
Loading ... Loading ...

The clock speed of computer processors has reached the ceiling and the processor manufactures have moved from developing even faster single core processors into developing processors with increasing number of cores on a single chip. The increasing number of parallel processors is a challenge for software industry as writing parallelly executing software with mainstream programming languages is a challenging job. This dilemma is sometimes referred to as the multicore crisis.

Even though writing parallel programs with languages like C++, Java or C# is a rather complicated job, programming for parallel environments doesn’t necessarily have to be a challenge. Two programming languages both having their roots in the end of 80′s, Erlang and LabVIEW, have both been inherently concurrent from the very beginning. Both languages have started as special purpose programming languages and during the last two decades evolved into full featured general purpose programming languages. Although being both inherently concurrent languages, Erlang and LabVIEW solve the problem of concurrency in rather different ways.

Message Passing Concurrency with Erlang

Erlang first appeared in 1987, and was developed by Swedish telecom giant Ericsson as a high level productive programming language for programming telecommunication network components. Good near-linear scalability and very high availability are core requirements of telecom network components. Erlang was developed with these requirements in mind. It provides excellent scalability with message passing concurrecy and has evolved into a incredibly stable environment allowing development of the most demanding high availability software.

Erlang is a message passing programming language build around functional core language. The basic building blocks of Erlang language are entities called processes. A process is a lightweight independent parallel execution environment that can communicate with other processes by exchanging messages. Each process has a mailbox into which messages sent to the port are delivered.

When a new process is created, the initially executed function needs to be defined by the spawning process. This function defines the initial state of the process. When a message is received, the next action is defined by matching the message against various patterns. To wait for the next message, the function either calls itself recursively or calls some other functions with message receiving ability.

The reply to messages, a process can send messages back to the sender. However this is possible only if the sender has included it’s own process id in the message. Below is an Erlang example of a process function loop that in respond to a message, computes the area of a geometric object and sends the reply back to the sender. The example is from the book Programming Erlang by Joe Amstrong.

loop() ->
	receive
		{From, {rectangle, Width, Ht}} ->
			From ! Width * Ht,
			loop();
		{From, {circle, R}} ->
			From ! 3.13159 * R * R,
			loop();
		{From, Other} ->
			From ! {error, Other},
			loop()
	end.

Dataflow Concurrency with LabVIEW

LabVIEW is a visual programming language and an integrated development environment developed by National Instruments. LabVIEW is mainly targeted for the development of engineering applications in the fields of automation, test and measurement. First version of LabVIEW was launched for Apple Macintosh in 1986, a little before Erlang first appeared.

LabVIEW is a dataflow programming language. Each element of the program is executed when the all data required by the element becomes available. At each instance of time, all elements that are ready for execution, are executed in parallel by LabVIEW multithreaded execution system. This parallel execution is possible, because data is never shared between two elements, but a copy of shared data is made instead. If two elements depend on the same data source, both will get their own independent copy of the data. As a result, dead-locks and race conditions do not exist.

In addition to following dataflow paradigm, LabVIEW is a visual programing language. Visual paradigm is very suitable for describing dataflow relationships. Program building blocks in LabVIEW are functions called virtual instruments or VIs for short. Each VI can have multiple input arguments and multiple output values. A program is constructed by laying VIs on a canvas called block diagram. The inputs of the VIs are connected to the inputs of other VIs. The directional data flow from one VI to another defines the execution order of the VIs. In addition to VIs, LabVIEW has many visual language primitives that behave in a similar manner.

Below is an example of a LabVIEW VI that opens a text file specified by input parameter, searches the file content for strings Bill and Gates in two loops executing in parallel, ANDs the boolean arrays returned by the loops and searches the ANDed array for values True. The VI returns the line numbers where both words Bill and Gates were found.

Example of a LabVIEW Program - Searching for Bill Gates

Conclusions

Both programming languages, Erlang and LabVIEW are inherently concurrent languages. However the models of concurrency are very different in these two languages. Whereas LabVIEW follows intuitive and simple-to-use dataflow concurrent model, Erlang is based on highly scalable message passing concurrency. Both models have their benefits and drawbacks. In dataflow programming, concurrency becomes almost automatically without extra effort. In a LabVIEW program all parallel elements are also executed in parallel. However writing programs in LabVIEW dataflow model that scale up to dozens of processors is rather complicated. Erlang on the other hand is more complicated to learn and to master. The Erlang message passing concurrent model requires more careful software architecture design. However, when implemented correctly, this concurrent programming model allows building applications that scale linearly to almost any number of processors. Again without race conditions.

My gut feeling is that neither of these languages will be the language of the future. Both languages are rather old and carry the weight of the history. However both of the languages have interesting and powerful characteristics that should be part of the future programming languages for the concurrent era.

Print This Post Print This Post

15 Comments

Make A Comment
  • Shane Said:

    This type of massive parallelism can be somewhat reproduced in LabVIEW using distinct code pieces linked by messaging queues (although more work may be required). By including a reference to the sender’s queue, the receiver can also take part in a two-way communication.

    I have thought about this approach for several special algorithms I have to allow run-time selection of how many threads can be allocated to a single problem. It’s quite viable. It can also be made work over a network connection, thus allowing for distributed computing.

  • Yen Said:

    Shane wrote:

    “By including a reference to the sender’s queue, the receiver can also take part in a two-way communication”.

    OpenG has something similar where a message queue also includes a response notifier reference.

    Tomi, how is the piece of Erlang code you posted different from calling a dynamic dispatch VI or a VIT or spawning X processes in advance and sending the command to one of the free ones?

    Also, did you manually type that code or did the book really list Pi as 3.13? ;)

  • Tomi Maila Said:

    You guys are correct, one can write LabVIEW code that behaves in a similar manner as Erlang processes. However this is not in the core design of LabVIEW so using asynchronous communications the Erlang way is not as flexible as in Erlang. Also the functional core language of Erlang makes the the message passing concurrency more powerful that the LabVIEW counterpart would be.

    Yen, calling a dynamic dispatch VI is a synchronous action. LabVIEW waits for the call to return until it continues the execution of the nodes following the caller. In Erlang the concurrent model is completely asynchronous; the sender doesn’t need to wait for the message to be handled.

    There is an additional major difference in the languages. Erlang processes are aware of the connections they have with other processes. When one process fails somewhere in this network of Erlang processes, the failing process broadcasts the failure to all the dependent processes. This way asynchronous error handling is independent of the messages sent between the two processes.

  • Tomi Maila Said:

    I forgot the pi, you’re right, I should have written 3. Didn’t a state legislature in a U.S. state once pass a law saying pi equals 3?

  • Guillaume Lessard Said:

    I’m not sure multithreaded concurrency is actually scalable in the long term. The Erlang approach is the right one, in that respect. I’ve used my own incomplete, home-built message-passing library for distributed applications in LabVIEW, and I wish LV had a native construct for this.

  • Shane Said:

    Tomi wrote “this is not in the core design of LabVIEW”. True. But the core design allows it. It’s not neccessary to get LV to do something contrary to its normal mode of operation.

    A dynamic dispatch VI is synchronous, but the actions taken by it may lead to asynchronous actions. Surely the “functions” within Erlang which actually performs the communication is in itself also synchronous. The next line of code is surely not executed before the previous one is executed.

    Tomi also wrote “Erlang processes are aware of the connections they have with other processes. When one process fails somewhere in this network of Erlang processes, the failing process broadcasts the failure to all the dependent processes. This way asynchronous error handling is independent of the messages sent between the two processes.”. This certainly sounds useful when building this kind of process, but it’s nothing which couldn’t also be achieved with LV. A lot of work maybe until its up and running, granted.

  • Shane Said:

    I realised I’ve posted 2 critical responses without saying ….

    Nice article Tomi. Thanks.

  • Jordan Wilberding Said:

    It would be interesting to see just how things will scale with LabVIEW. I have used LabVIEW quite alot, and one of the headaches is that with each split(copy) of data, you are double, tripling, etc. your memory requirements. Even in the world where most computers have at 1-2GB of RAM, memory can quickly run out for large applications. Erlang does things a little different, and memory isn’t being allocated all the time.

    I really wish an open source LabVIEW program would come out. Programming visually like LabVIEW does lends itself well to a lot of applications.

  • Tomi Maila Said:

    Jordan, I’ve understood that when you send a message to a process in Erlang, Erlang creates a copy of the data sent. Am I incorrect here?

  • Jordan Wilberding Said:

    Tomi,

    Yes you are correct. As far as spawning new processes to process the data it is about the same. I was thinking more about the spawned processes themselves.

    I am no expert, but from having used LabVIEW it appears to me that whenever you perform an operation on a stream of data, a new copy is made. For instance, if you had an Array in LabVIEW and passed it through a sorting VI, it would create a brand new copy of the array. So now you have two full copies of the array, one that is sorted as output, and still the input that is not sorted.

    With Erlang, you could program it in such a way that no new space is allocated from the sort, it just replaces the input memory location that was used.

    So I think it would be hard to scale LabVIEW because VI just isn’t as good at handling memory from the spawned VIs. It works great for building apps it was intended for, but when data gets big, or concurrency increases, the memory issues becomes important.

  • Frederico Said:

    >In Erlang the concurrent model is completely asynchronous; the sender doesn’t need to wait for the message to be handled.

    The sender still needs to wait for the message to arrive at the other end, otherwise message passing could not be guaranteed to be reliable. This is not “completely asynchronous” as network or Inter-Processor Interrupt contentions for example can lead to livelock.

  • Tomi Maila Said:

    > This is not “completely asynchronous”…

    Thanks Frederico for these details. :)

  • Tomi Maila Said:

    > I am no expert, but from having used LabVIEW it appears to me that whenever you perform an operation on a stream of data, a new copy is made.

    These memory allocation blocks in LabVIEW are called buffers. Usually an output of an operation is written into a new buffer. However in the newest version of LabVIEW 8.5 an in-place memory structure was introduced. This allows writing programs that operates buffers in-place. However, currently most of LabVIEW libraries are written without using these new in-place memory structures. As a result you can currently write memory efficient code with LabVIEW, however libraries you use may screw up your memory efficiency.

  • Albert Said:

    Hi Tomi

    Nice to give us insight in completely other languages. Although I like to read about it I do not forget why we choose LabVIEW. It is a very good language for instrument control and has excellent (not all) libraries for a lot of hardware.
    And I can program low-level and high level in the same environment. (this of course also applies to C but I feel good with the multiprocessor style in LabVIEW.
    thanks for keeping us not too narrow sighted

  • Active VI Toolkit public alpha - Erlang style message passing concurrency toolkit for LabVIEW - ExpressionFlow Said:

    [...] few months ago I compared the LabVIEW and Erlang concurrency models in my article Two Paths to Concurrency – Comparing Erlang and LabVIEW. Whereas Erlang concurrency model provides means to write highly concurrent highly scalable [...]

Comments RSS Feed   TrackBack URL

Leave a comment

You must be logged in to post a comment.

Get Adobe Flash playerPlugin by wpburn.com wordpress themes