Energy reduction techniques for caches and multiprocessors