Amdahl's law doesn't have anything to do with memory bandwidth. It's very simple, and trust me, there is no way around it. Some algorithms, or parts of algorithms, cannot be parallelized; they are inherently serial.
Let me put this question to you: what stops serial processing tasks being shared amongst different cores?
The issue with parallelising serial tasks is not the access to more cores, as out-of-order execution shows it's possible to streamline processing based on the computing resources available. What does hold things back is that the memory holding the data being worked on is not shared out. That is why I stated that commonly employed memory architectures are the bottleneck. If it helps, think about it like this. What we have now is multiple cores working on a single data set. Now think about a network of computers working on a problem together. A key part of making this efficient is ensuring they block each other as little as possible. Now consider that it's possible to build a 'network' of computers within a single computing device, so long as they have control of their own memory. Hopefully you can see where this is going, if not this page should give a little more clues:
http://www.eetimes.com/design/eda-design/4211228/Overcoming-32-28-nm-IC-implementation-challengesAmdahl's Law applies only to a certain set of programs. Yes, there are parts of algorithms that must be executed in a certain order. However, there are many ways to write code that lends itself to parallel execution. Here's one example of an article that discusses ways to beat Amdahl's law:
http://drdobbs.com/cpp/205900309?pgno=1Generally speaking, one of the key things when designing programs that are highly parallelised is avoiding the need to manipulate state. For example, the programming language Haskell is 'pure' by design in the sense that it doesn't alter the state of program whilst running it, and the elements of the program that do require changing state and the side effects from this are sandboxed in structures called monads. This allows Haskell programs to take advantage of multi-core CPUs without needing to worry about program execution.
If this is new, need to explore what is meant by side effects. Imagine if every time you asked a certain question you got the same answer. Having such a question in a program is an example of something without side effects. Next, imagine the opposite. With the question with side effects, the answer is partly determined by when you ask it. By removing side effects, it doesn't matter when you ask the question.