Asynchronous Versus Parallel Programming
The last decade has brought about the age of multi-core processors to many homes and businesses around the globe. In fact, you would be more hard-pressed to find a computer with no multi-core (either physical, or virtual) support for sale on the market today. Software Engineers and Architects have already started designing and developing applications that use multiple cores. This leads to extended use of Asynchronous and Parallel programming patterns and techniques.
Before we begin it would help to review a key difference in Asynchronous and Parallel programming. The two perform similar tasks and functions in most modern languages, but they have conceptual differences.
Asynchronous calls are used to prevent “blocking” within an application. For instance, if you need to run a query against a database or pull a file from a local disk you will want to use an asynchronous call. This call will spin-off in an already existing thread (such as an I/O thread) and do its task when it can. Asynchronous calls can occur on the same machine or be used on another machine somewhere else (such as a computer in the LAN or a webserver exposing an API on the internet). This is used to keep the user interface from appearing to “freeze” or act unresponsively.
In parallel programming you still break up work or tasks, but the key differences is that you spin up new threads for each chunk of work and each thread can reach a common variable pool. In most cases parallel programming only takes place on the local machine, and is never sent out to other computers. Again, this is because each call to a parallel task spins up a brand new thread for execution. Parallel programming can also be used to keep an interface snappy and not feel “frozen” when running a challenging task on the CPU.
So you might ask yourself “Well these sound like the same deal!” In reality they are not by any means. With an asynchronous call you have no control over threads or a thread pool (which is a collection of threads) and are dependent on the system to handle the requests. With parallel programming you have much more control over the tasks chunks, and can even create a number of threads to be handled by a given number of cores in a processor. However each call to spin up or tear down a thread is very system intensive so extra care must be taken into account when creating your programming.
Imagine this use case: I have an array of 1,000,000 int values. I have requested that you, the programmer, make an addition to each of these people objects to contain an internal id equal to the object’s array index. I also tell you about how the latest buzzword on the street is “multi-core processing” so I want to see patterns on that used for this assignment. Assuming you have already defined the original “person” class and wrote a “NewPerson” class with the added dimension, which pattern (asynchronous or parallel) would be preferred to break the work up and why?
The correct answer of course would be the parallel pattern. Since each object is not dependent on another object from somewhere else (from something like a remote API) we can split the million objects into smaller chunks and perform the object copy and addition of the new parameter. We can then break send those chunks to different processors to conduct the execution of our code. Our code can even be designed to account for n processors in any computer, and evenly spread the work across CPU cores.
Now here at Mercer I am working on a .NET web product. Our tech leads and developers have created a “Commons” library that contains factories and objects that are useful to all the sub-projects that exist in this very large .NET product. Exposed services or factories are hosted via IIS and are accessible by other projects in the product by simply referring to the “Commons” namespace. Basically the “Commons” library prevents all developers from re-inventing the wheel if they need things such as a log writer, methods to extract objects from a MSSQL database, or even methods for interoperability between projects.
When it comes to the “Commons” library we are using Asynchronous calls between the server and client. We do this since a user could potentially hit one server in the cluster, then make another request that is picked up by a separate server in the cluster. It would not be helpful if we spun up a processing thread on Server A, only for the client to hit Server B (which then would have to spin up its own thread) if the cluster load balancer redirects them to Server B. Since our services are built to be asynchronous calls, all the client end has to do is pass in some session information to the server and the server can pull up the requested objects or data. If we were to use parallel processing in regards to the .NET pattern, we would be creating a ton of overhead with the constant setup and tear-down of threads within the webserver. There is also a chance the client might be redirected to another server completely by the forward facing load balancer. For our “Commons” it makes much, much more sense to just let the operating system handle sending off and receiving asynchronous calls.
So this should have served as a basic compare and contrast of asynchronous and parallel programming. If you remember anything, remember this: While both patterns are used to prevent blocking within, say a User Interface, keep in mind that an asynchronous calls will use threads already in use by the system and parallel programming requires the developer to break the work up, spinup, and teardown threads needed.