Nobody said anything about not having NTP in the loop!
Here's the deal: RPi<5 runs at the speed of the voltage coming in. The OS creates a fake software clock that assumes it's a perfect 5v, but in reality not only does voltage fluctuate, it drops over the length of a cable run. If you have, I dunno, 70 Pis connected, the 5v on the first one is very different than the 5v on the last one, no matter how frequently you ask NTP to broadcast.
The first thing we did was deliver 12V down the wire with a high quality power supply. Then we used UBEC buck converter modules (intended for RC quadcopters) to deliver power directly into the Pi via its pins.
However, even now you're just chasing physics. There's no way to send a command to all of the Pis to do something right now. Instead, we tell all of them to do something at a very precise moment in about three seconds. In our case, this meant writing a very low-level C program to listen for raw UDP messages and trigger the camera module at the hardware register level.
The only way to verify that it was working as well as we believed it did was to create a reference clock. We had a friend build a 20 LED timer that would count 10ms and 1ms increments.
We achieved < 1ms syncronization across 70 Pis in this manner.