As memory increases in size and capacity, it becomes slower and slower, as a general tendency of hardware. As memory decreases in size and capacity, it tends to become faster and more responsive.
If you have a processor operating at 1,000x, or even 10x the speed of the memory it is attempting to access, then the speed of computation will be reduced to match the pace of the slowest bit of hardware in the system!
To mitigate this, caches act as a middle road between two sets of memory, allowing the processor to access memory that is frequently being used, or that might be used next, more quickly and more effectively.
The cache acts as a middle road between slower (bigger) and faster (smaller) memory by mapping all possible addresses in the larger memory to some middle size and speed.
Caches are generally divided into a number of sets, and each of those sets contain lines, which hold a number of adjacent bytes of memory.
Addresses can then be divided up, from the number of bits that represent them (a), into 3 relevant fields, the offset (f), the index(i), and the tag(t).
The offset (f) is found by taking the least significant log2(block size in bytes) bits of the address. This number gives the offset, within the correct line and in bytes, of the piece of memory that is being requested.
The index (i) is found by taking the next log2(number of sets) bits of the address. This number gives the index of the set that will hold the matching lines that may hold the piece of memory being requested.
The tag (t) is found by taking the remaining bits of the address.
Finding a line that holds relevant data is done by checking the tag, and whether or not the data is valid (it is possible for the cache to have residual values from previous power cycles). If all conditions are met, then the relevant blocks are selected and served up to the faster memory.
Direct mapped caches are caches that contain a larger number of sets, each with only one line.
Set associative caches are caches that contain only one set, and a larger number of lines.
Generally, caches go somewhere between the two, finding a balance between the number of sets and the number of lines.