Yes, that is what Hodgman is saying; vsync blocks until the display is ready for another frame.
But why does the slowdown only occur after several seconds, then? To clarify, at first everything is just like without VSync, with phystick showing 16-17 every frame (that's got to mean first "if" fires 16.(6) times as often as the second one... right?). Then it slowly drops. And even so, it stays higher than 1, so "while(true)" must be firing at more than 60Hz.
Traditionally, enabling vsync would mean that the "Present" function would block until a vblank period was reached, which would be once every 16.6ms for a 60Hz display (note that some displays may be 59Hz, or 72Hz, etc... so your MaxFPS parameter needs to be configurable).
However, this isn't necessarily true any more. Vsync means that the driver will implement a frame-limiter on the GPU, so that it only displays images in sync with the display's refresh rate. If you feed it images faster than that (calling present == giving the GPU an image to display), then instead of blocking, the driver can choose to queue up those images.
e.g. Say the driver can queue up 10 images at once -- then if you call Present 11 times in a row really quickly, the first 10 will complete immediately, and the 11th will block.
Basically, when you call any D3D function, you're just putting commands into a queue, which the GPU will execute later. If this queue gets too full, then Present will block until the GPU has emptied it enough. If vsync is on, then at some point Present is likely to block for a large amount of time, such as 16ms, so your loop has to be able to deal with jumps in time that are at least about that big.
Anyway, regardless of whether you're using vsync or not, your current game-loop/timer code is broken. For your code to work, you're assuming that the amount of work done per frame will always be less than 1ms. If drawing a frame and/or processing the physics ever takes more than 1ms, your physics will go into slow motion.
You cannot draw or simulate very much stuff in 1ms, so your game loop will only work for very simple games, or on very high performance computers. If you add more "stuff" to your game, it will go into slow motion due to each iteration of your loop taking more than 1ms...
On a side note: If your physics update ever takes more CPU time than your fixed timestep (e.g. if at the moment, the ProcessPhysics took more than 1ms to complete), you're in bigger trouble though - because there'd be no way to fix that. If 3ms has passed since the last update, you need to update your physics 3 times in order to not go into slow motion... but if each update takes the CPU 2ms to complete, then now 6ms has passed, so you'll have to update physics 6 times (which will take 12ms, etc, etc). To mitigate this, I'd suggest using a much lower fixed-timestep than 1000Hz.
1000Hz is really quite extreme for physics - you probably don't need it to be that precise, usually even 30Hz is enough.
I'm making a racing simulation game, which requires a lot of accuracy, so I update most of my physics at 60Hz, and just the car wheels (which is the most important part) are updated at 600Hz.
Regarding the "physicsAccumulator": I've considered passing the time since the last physics iteration to ProcessPhysics(), so that it would advance the game world by that amount, but then, if a game were to freeze momentarily, there would be a skip. I thought it would make quite a mess of things, so I've decided to use a fixed step size.
As above, your fixed step size has the other draw-back of causing your game to run in slow motion. You can create a hybrid of the two, which uses an accumulator but also has a maximum-updates-per-render setting to avoid big jumps.
uint64 physicsAccumulator = 0;
while(true)
{
physicsAccumulator += ticks passed since last iteration
int physicsSteps = physicsAccumulator / ticksPerPhysicsUpdate
physicsAccumulator -= physicsSteps * ticksPerPhysicsUpdate // i.e. physicsAccumulator = the remainder
if( physicsSteps > max updates per render )
physicsSteps = max updates per render;//avoid large jumps if the game has been stalled
for(int i=0; i!=physicsSteps; ++i)
{
Advance physics by fixed time step
}
Draw
}