Async in a nutshell : Why developers should write processor killing codes

Buddhika Chathuranga
RuntimeError
Published in
5 min readOct 8, 2019

These days most of the companies don’t have their own processing power. They hire processing power through infrastructure services like Amazon. So developers have a huge responsibility in order to write processor killing codes (I’ll explain that later). That is why asynchronous programming has become a trending topic in the tech world. If you are really new to asynchronous programming it is better to read the first article of this async in a nutshell series, Get into async before you start reading this. In this article we are going to discuss synchronous, asynchronous and multi-threading with respect computers using some rather silly examples just to make it easier for everyone.

First lets us understand why we needed asynchronous programming. To understand this, it is important to be aware of processor bound operations and I/O bound operations. In a computer system there are few types of operators such as processor bound operations, I/O bound operations, memory-bound operations so on. But here we care only about processor bound operations and I/O bound operations. Processor bound operations are the operations that depend on the processor such as doing an arithmetic calculation. I/O bound operations are the operations that do not directly depend on the processor but on the I/O peripherals such as fetching data from a database through an HTTP request or write or read data from a file which is located in the hard disk.

If simply explained, we say that a program is a processor bound program if the program runs faster if the CPU were faster and a program is I/O bound program if the network subsystem was faster. Refer to the image below.

Imagine the function named GetDataOnline() is a function that fetches data from an API endpoint through an HTTP request. Imagine that request takes about 3 seconds to fetch data from the internet. So the code lines below that function call will have to wait until that request to finish or time out before executing. That doesn’t seem like a big problem. But imagine this is the UI thread of the program and when the program is blocked we can’t control the UI. This means we can’t minimize, move or even close the program until the GetDataOnline() function is finished. That is a very bad user experience. This becomes the worst when it comes to something like a web server. Imagine the server has to wait until it finishes some database queries to handle another request. That’s totally enough to destroy the whole business.

So there are few workarounds to tackle this problem. One approach is multi-threading. Nowadays almost all the computer systems have multi-cores. The core is a single processing unit that can do a task. When there are multi-cores it is possible to do many tasks at once. Even though there is a single core it is still possible to do several tasks at once. But what actually happens there, is time-slicing between the tasks (threads). However when there are multi-cores in a computer system then we can hand over the responsibility of different tasks (threads) to different cores. Then those cores can work in isolation. But the problem starts when those threads start to work with common resources like memory. When those threads interact with common resources its really difficult to manage the synchronization between the threads and it becomes really hard to communicate between those threads. This is why asynchronous programming is important.

The asynchronous program does not consume extra threads to do these I/O bound operations. Instead, Asynchronous programming uses futures and callbacks. Actually the processor should not need to wait until I/O operations are finished. Look at the image given below.

Imagine GetDataFomFile() is a function that fetches data from a file in the hard disk. Imagine it takes about 3 seconds to finish this task. Now again the code below the GetDataFromFile() has to wait until this task finished. But in asynchronous programming it doesn’t happen in this way. In asynchronous programming the OS just hands over that process to the device driver which executing the I/O operation and continues with the code below the GetDataFromFile(). It does so by first constructing an object that represents the read request. This is called an I/O request packet (IRP).

The device driver receives the IRP and issues a command to the device to write out the data. If the device supports Direct Memory Access (DMA), this can be as simple as writing the buffer address to a device register. That’s all the device driver can do; it marks the IRP as “pending” and returns to the OS.

See, it did not create an extra thread or wait until GetDataFromFile() finished. When the task eventually finishes, the program can continue with it. There may be some service threads in order to handle this callback. But still this is better than synchronize executing or multi-threading, isn’t it? Since we are not waiting for the processor until I/O operations happen we can utilize the processor as much as we pay. We can kill the processor.

There is a great article on asynchronous programming There is no thread which you can refer.

In general it is not really easy to write asynchronous code, but latest frameworks have made it much easier and provide a lot of support. So, in next article let us see how to write an asynchronous program using C# and asp.net framework.

--

--