Citizen,
What software are you using (I am assuming RSLogix5000 here)?
What we have done successfully is create a User-Defined datatype (UDT) that was an array of PID loops. We have a similar situation where we have multiple units each with a PID loop for a given function.
We made the code generic enough so that each unit had it's own instance of whatever function we needed. So for lets say a Pressure Control module, we made a UDT for Pressure Control and embedded the Pressure Control Array of PID loops within the UDT. The code would loop through each unit and also indirectly evaluate the PID loop, so if you made a PID UDT called PressurePID you could do this:
PressurePID [ Unit_Index]
In our case, it was:
CM_PressureControl . PressurePID . [Unit_Index]
You don't have to embed the Pressure PID UDT in another tag, and outside of the control module, independently loop through the PID UDT array for each unit.
Unfortunately when you view the ladder logic, in RSLogix you cannot (as of Rev17) view the Output, PV, SP ,etc from the PID instruction if it is indiretly referenced in the Ladder you would have to either drill down to the PID tag in the tag browser or Edit the rung and replace the unit index with what instance of the PID loop you wanted to look at. You don't have to accept the edits to do this.