Welcome back. We are starting to talk about multi-phrasing with openMP. Central to this topic is the concept, of course, and the related topics of processes and threads. As you know, just over a decade ago, most processors were single core. And they would only be able to efficiently run a single stream of instructions. Of course, you could still do multitasking in the operating system, but multiple streams of instructions would share the same core. Today, if you look at data centers, you find multi-core processors and many core processors and co-processors such as Xeon and Xeon Phi. In both of these classes of processors, you find tens of course. For example, second generation Intel's Xeon Phi processor has up to 72 to execution cores. Applications must know about the multi-core aspect of the architecture. If your application doesn't know anything about the multiple cores, then it has only a single stream of instructions that will only occupy a single processor core. And most of the cores will go unused. As the programmer, you have to enable support for multiple cores and to do that, you have to run multiple streams of instructions. There are two ways to do that. One way is multi-processing. The other is multi-threading. Processes in Linux are streams of instructions, each with its own memory address space. In contrast, threads are independent stream of instructions that have common memory address space. So there are going to be differences in the way that you design parallel programs with threads and with processes. We will talk about multi-threading in this lecture, number two, and we will talk about multi-processing and message passing in lecture five. The key difference is that if you want to exchange some data between processes, you have to pass messages, most commonly across a communication fabric. With threads you don't have to do that. If one thread is responsible for half of the simulation domain and the other thread is responsible for the other half, then thread one can transparently read data that you assigned to thread two. There is a distinct advantage of multi-threading over multi-processing in the ability to share memory between threads. If you have a large data structure, particularly a data structure that you only use for reading, then in the case of processing, multi-processing, you will have to keep a copy of this data structure in the memory of every process. This is of course assuming that every process needs the entire data structure and not a part of it. With threads, you don't have to do that and you can keep just one copy for concurrent reading by multiple threads. We will talk about creating threads and assigning work to them in the next video.