Amdahl’s Law and Moore’s Law
Alright, we’ve covered the practical synchronization primitives. Now, let’s step back and look at two fundamental laws that dictate the potential and the necessity of concurrent programming in hardware and software development. These are more theoretical but crucial for understanding the “why” behind multithreading.
9. Amdahl’s Law
Concept:
Amdahl’s Law is a formula that gives the theoretical speedup in latency of execution of a task at fixed workload that can be expected of a system whose resources are improved. In simpler terms, it states that the maximum speedup you can gain by parallelizing a program is limited by the sequential (non-parallelizable) portion of that program.
- Analogy: Imagine preparing a multi-course meal.
- Some parts can be done in parallel (e.g., one chef chops vegetables, another prepares the sauce, a third bakes bread). This is the parallelizable portion.
- However, there are also inherently sequential parts (e.g., only one oven is available, so dishes must be baked one after another if they need different temperatures; or the final plating of all dishes must be done by one person at the very end). This is the sequential portion.
- No matter how many chefs you hire, the overall time to prepare the meal will always be limited by the time taken for those sequential steps. If the final plating takes 30 minutes, you can’t get the meal out faster than 30 minutes, even with a thousand chefs for the prep work.
- Formula:
Speedup (S) = 1⁄(1-P) + P⁄N- P: The proportion of the program that can be parallelized (a value between 0 and 1).
- (1-P): The proportion of the program that is strictly sequential (cannot be parallelized).
- N: The number of processors (CPU cores) available.
- Implication:
- As N (number of processors) approaches infinity, the term P⁄N approaches 0.
- Therefore, the maximum theoretical speedup approaches 1⁄(1-P).
- This means if even a small percentage of your program is sequential (e.g., P = 0.9, so 1-P = 0.1 or 10% is sequential), your maximum speedup will only ever be 1 / 0.1 = 10x, regardless of how many cores you add. This highlights that identifying and minimizing the sequential parts of your code is crucial for gaining significant benefits from parallelism.
Practical Relevance (Why it Matters in Production):
- Performance Bottlenecks: Amdahl’s Law helps you understand why simply throwing more threads or more CPU cores at a problem won’t always give you a linear performance improvement. You need to profile your application to identify the truly sequential bottlenecks.
- Design for Parallelism: It encourages developers to design algorithms and data structures that maximize the parallelizable portions and minimize the sequential synchronization points.
- Diminishing Returns: It explains the diminishing returns of adding more cores. After a certain point, the overhead of managing parallelism (context switching, synchronization) and the inherent sequential parts of the program outweigh the benefits of adding more processing units.
Example Scenario:
Imagine a task where:
- 90% of the task can be parallelized (P = 0.9).
- 10% of the task must run sequentially (1-P = 0.1).
- With 2 processors (N=2):
Speedup = 1⁄(0.1) + 0.9⁄2 = 1⁄0.1 + 0.45 = 1⁄0.55 ≈ 1.82x - With 10 processors (N=10):
Speedup = 1⁄(0.1) + 0.9⁄10 = 1⁄0.1 + 0.09 = 1⁄0.19 ≈ 5.26x - With 100 processors (N=100):
Speedup = 1⁄(0.1) + 0.9⁄100 = 1⁄0.1 + 0.009 = 1⁄0.109 ≈ 9.17x - Theoretical Maximum (as N → ∞):
Speedup = 1⁄0.1 = 10x
As you can see, even with a huge number of processors, we can’t get more than a 10x speedup because of that 10% sequential part. This is why optimizing critical sections and minimizing necessary synchronization is so important.
10. Moore’s Law
Concept:
Moore’s Law is an observation (not a physical law) made by Gordon Moore, co-founder of Intel. It states that the number of transistors on a microchip roughly doubles every two years.
- Analogy: Imagine the size of a chef’s workstation. For decades, Moore’s Law meant that every two years, you could cram twice as many tiny kitchens (transistors) onto the same amount of counter space, making individual kitchens more powerful and faster.
- Historical Implication: For many years (roughly from the 1970s through the early 2000s), this directly translated into faster CPU clock speeds. Programs would automatically run faster on new hardware even without code changes. This was often referred to as “getting free performance.”
- Modern Implication (The “End” of Clock Speed Scaling): Around the mid-2000s, chip manufacturers started hitting physical limits related to heat dissipation and power consumption. They could no longer reliably increase clock speeds exponentially. Instead, to continue the trend of increasing processing power, they started increasing the number of cores (i.e., multiple independent processing units) on a single chip.
Relevance to Java Concurrency (Why it Matters in Production):
- The Shift to Multi-Core: Moore’s Law’s evolution is the primary reason why concurrency and multithreading have become absolutely essential for software development.
- No More “Free Performance”: If your application is still primarily single-threaded, it won’t benefit significantly from new hardware with more cores. It will only utilize one core, while the others remain idle. The “free performance” era for single-threaded applications is largely over.
- Necessity of Parallelism: To leverage modern multi-core processors and future hardware advancements, applications must be designed to be multi-threaded and take advantage of parallelism. If you want your software to get faster with new hardware, you have to write concurrent code.
- Driving Concurrency Libraries: This shift in hardware design has also driven the development of sophisticated concurrency libraries and frameworks in languages like Java (
java.util.concurrent
package), making it easier (though still challenging) to write correct and efficient concurrent code.
Summary for Production:
Amdahl’s Law tells us the limits of parallelism based on our software design (focus on minimizing sequential parts).
Moore’s Law (and its evolution) tells us why parallelism is now a necessity in hardware; it’s the dominant way to get more computational power from chips.
Together, they form the fundamental economic and technical drivers behind the importance of learning and applying concurrent programming principles in modern software development.
This concludes our “Basics” section. We’ve covered the fundamental concepts from Program to Process to Thread, the critical issues like Race Conditions and Deadlocks, the basic synchronization primitives, and the underlying hardware/software laws.
Next, we’ll dive into the specific multithreading features in Java, starting with Atomic Assignments and revisiting Thread Safety & Synchronized in more detail.
Are you ready for Multithreading in Java: Atomic Assignments?