Why this course, and what's in it for you? High performance computing is everywhere these days. This slide outlines the most important areas. To be just a little bit more specific, I will name only one application in each of these areas. So, high performance computing or HPC is used in medicine for high fidelity imaging, in the energy sector for oil reservoir simulation, in environmental studies to predict climate and weather, in manufacturing it is used to optimize the fuel efficiency of new automobiles and aircraft. HPC is used in data analytics to make marketing smarter and to automate it. In artificial intelligence HPC allows you to speak to your smartphone and get it to do useful things. In financial applications HPC is used for risk analysis, and in natural sciences for example, to invent new materials. What's common across all of these disciplines is the need for performance. And performance means different things for different users. Sometimes what you want is shorter time to insight, to solve your problem faster. For example, with financial risk analysis you often want to trigger a good transaction faster than your competitors. Sometimes performance means better power efficiency, and performance allows you to do the same work with less power. This applies to the largest data centers, and also to the smallest computational devices powered by batteries, such as smartphones. Performance may be necessary to reduce hardware costs. So you can do the same work with less investment in computational systems. Think of self-driving cars. They require a lot of computer power on-board at a competitive cost. And finally, good performance may allow you to tackle greater problems, and get better scientific insight. For example, if you are using a Monte-Carlo simulation to predict a radiation treatment strategy, then running more statistics within the allowed time frame allows you to get a more accurate prediction of the risks and benefits for that patient. And of course, computer architecture gets better and faster with every generation. But, we will see in this course that there is an absolute prerequisite for getting more performance out of the novel platforms, and that is optimize software. Software that solves real world problems must be aware of the new features of the novel architectures. In particular, it must be able to handle parallelism. There are multiple layers of parallelism in modern architectures, and from the top, the highest level of parallelism is distributed memory systems. If you connect multiple computers into a network you get a computing cluster, and computing clusters have existed since the early days of computing. Computers in a cluster are commonly called compute nodes, but your application will not use all of the compute nodes in a cluster, unless you teach it to do so using a framework for distribute computing, such as MPI. Around a decade ago, processor architectures changed in such a way that every compute node now has multiple independent processors inside of it, called cores. This is the second layer of parallelism. And again, if you want to teach your program to use cores, you have to use a framework for parallel computing in shared memory such as openMB. Finally, in recent years cores themselves have evolved. So now they can run their instructions on multiple data elements at once. This functionality is usually implemented as short vector support, and this is yet another layer of parallelism. If you want your software to handle this type of parallelism you need to structure your code in a certain way, and usually you need to interact with the compiler to implement vectorization. Techniques for handling parallelism in computational applications are often not a part of the standard curriculum on computing and computer programming. And this is why we are teaching this course. And in the next video we will talk about how computers are getting faster these days, and why you as the programmer need to know about it.