In most systems IO was the bottleneck. Accessing the disk drives or other devices like tape drives took orders of magnitude more time than accessing the main computer system memory. Large systems like I worked on at Burroughs had what is called multiport main memory. What that means is that more than one processor can access the memory, and if designed properly that happens with minimal overhead. In other words more than 99% of the time the main processor and IO processor can access memory simultaneously. This required a lot of hardware and some tricks, but by the 1980’s it was common practice on large mainframes like the Burroughs B7800.
Smaller mainframes and mini-computers used a different architecture. They had a main processor and an IO processor that interfaced to the memory controller. The memory controller would select which processor could access memory. If either processor needed to access memory and there was no contention, that processor got immediate access. If both the main and IO processor needed to access memory, the memory controller would interleave the access. That meant either the main or IO processor may have to wait a memory cycle to get the data. In a worst case situation where both processors were consistently requesting memory access, the memory bandwidth would be cut in half. Some systems used special logic that might give one or the other processor priority under certain circumstances. The B5900 which I designed worked this way.
PC’s were low cost computers. To save money the designers use a single port memory and a shared data bus. Small minicomputers also used this architecture. What that means is that at any one time only one processor or can be accessing memory. The processor did all IO data operations. For example, if you type a key, the keyboard sends an eight bit character to a register connected to the PC bus. When that register is loaded an interrupt is generated which causes the microprocessor to stop what it is doing and then go get the byte of data from the register on the data bus and transfer it to memory (which is also attached to the data bus). This happens for every single character you type.