Optimal checkpointing strategies for iterative applications