Improving your C# Skills
上QQ阅读APP看书,第一时间看更新

Utilizing multiple cores of the CPU for high performance

These days, the nature of applications focuses more on connectivity, and there are cases where their operations take more time to execute. We also know that nowadays, all computers come with a multi-core processor, and using these cores effectively increases the performance of the application. Operations such as network/IO have latency issues, and the synchronous execution of the application program may often lead to a long waiting time. If the long-running tasks are executed in a separate thread or in an asynchronous manner, the resulting operation will take less time and increase responsiveness. Another benefit is performance that actually utilizes multiple cores of the processor and executes the task simultaneously. In the .NET world, we can achieve responsiveness and performance by splitting the tasks into multiple threads and using classic multithreading programming APIs, or a more simplified and advanced model known as the task programming library (TPL). The TPL is now supported in .NET Core 2.0, and we will soon explore how it can be used to execute tasks on multiple cores.

The TPL programming model is based on the task. A task is a unit of work—an object's representation of an ongoing operation.

A simple task can be created by writing the following lines of code:

static void Main(string[] args) 
{ 
  Task t = new Task(execute); 
  t.Start(); 
  t.Wait(); 
} 
 
private static void Execute() { 
  for (int i = 0; i < 100; i++) 
  { 
    Console.WriteLine(i); 
  } 
}

In the preceding code, the task can be initialized using a Task object, where Execute is the computational method that is executed when the Start method is called. The Start method tells the .NET Core that the task can start and returns immediately. It forks the program execution into two threads that run concurrently. The first thread is the actual application thread and the second one is the one that executes the execute method. We have used the t.Wait method to wait for the worker task to show the result on the console. Otherwise, once the program exits the block of code under the Main method, the application ends.

The goal of parallel programming is to effectively use multiple cores. For example, we are running the preceding code in a single-core processor. These two threads will run and share the same processor. However, if the same program can run on a multi-core processor, it can run on multiple cores by utilizing each core separately, increasing the performance and achieving true parallelism:

Unlike TPL, the classic Thread object doesn't guarantee that your thread will be running on distinct cores of the CPU. With TPL, however, it guarantees that each thread will run on the distinct thread unless it reaches the number of tasks as per the CPU and shares the cores.