Dealing with Non-Idealities in Memristor Based Computation-In-Memory Designs