<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Tue, Oct 16, 2018 at 4:07 PM Keith Packard <<a href="mailto:keithp@keithp.com">keithp@keithp.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Jason Ekstrand <<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>> writes:<br>
<br>
> I think what Bas is getting at is that there are two problems:<br>
><br>
>  1) We are not sampling at exactly the same time<br>
>  2) The two clocks may not tick at exactly the same time.<br>
<br>
Thanks for the clarification.<br>
<br>
> If we want to be conservative, I suspect Bas may be right that adding is<br>
> the safer thing to do.<br>
<br>
Yes, it's certainly safe to increase the value of<br>
maxDeviation. Currently, the time it takes to sample all of the clocks<br>
is far larger than the GPU tick, so adding that in would not have a huge<br>
impact on the value returned to the application.<br>
<br>
I'd like to dig in a little further and actually understand if the<br>
current computation (which is derived directly from the Vulkan spec) is<br>
wrong, and if so, whether the spec needs to be adjusted.<br>
<br>
I think the question is what 'maxDeviation' is supposed to<br>
represent. All the spec says is:<br>
<br>
 * pMaxDeviation is a pointer to a 64-bit unsigned integer value in<br>
   which the strictly positive maximum deviation, in nanoseconds, of the<br>
   calibrated timestamp values is returned.<br>
<br>
I interpret this as the maximum error in sampling the individual clocks,<br>
which is to say that the clock values are guaranteed to have been<br>
sampled within this interval of each other.<br>
<br>
So, if we have a monotonic clock and GPU clock:<br>
<br>
          0 1 2 3 4 5 6 7 8 9 a b c d e f<br>
Monotonic -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-<br>
<br>
          0         1         2         3<br>
GPU       -----_____-----_____-----_____-----_____<br>
<br>
<br>
gpu_period in this case is 5 ticks of the monotonic clock.<br>
<br>
Now, I perform three operations:<br>
<br>
        start = read(monotonic)<br>
        gpu   = read(GPU)<br>
        end   = read(monotonic)<br>
<br>
Let's say that:<br>
<br>
        start = 2<br>
        GPU = 1 * 5 = 5 monotonic equivalent ticks<br>
        end = b<br>
<br>
So, the question is only how large the error between GPU and start could<br>
possibly be. Certainly the GPU clock was sampled some time between<br>
when monotonic tick 2 started and monotonic tick b ended. But, we have<br>
no idea what phase the GPU clock was in when sampled.<br>
<br>
Let's imagine we manage to sample the GPU clock immediately after the<br>
first monotonic sample. I'll shift the offset of the monotonic and GPU<br>
clocks to retain the same values (start = 2, GPU = 1), but now<br>
the GPU clock is being sampled immediately after monotonic time 2:<br>
<br>
                w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f<br>
Monotonic       -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-<br>
<br>
          0         1         2         3<br>
GPU       -----_____-----_____-----_____-----_____<br>
<br>
<br>
In this case, the GPU tick started at monotonic time y, nearly 5<br>
monotonic ticks earlier than the measured monotonic time, so the<br>
deviation between GPU and monotonic would be 5 ticks.<br>
<br>
If we sample the GPU clock immediately before the second monotonic<br>
sample, then that GPU tick either starts earlier than the range, in<br>
which case the above evaluation holds, or the GPU tick is entirely<br>
contained within the range:<br>
<br>
          0 1 2 3 4 5 6 7 8 9 a b c d e f<br>
Monotonic -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-<br>
<br>
           z         0         1         2         3<br>
GPU      __-----_____-----_____-----_____-----_____-----<br>
<br>
In this case, the deviation between the first monotonic sample (that<br>
returned to the application as the monotonic time) and the GPU sample is<br>
the whole interval of measurement (b - 2).<br>
<br>
I think I've just managed to convince myself that Jason's first<br>
suggestion (max2(sample interval, gpu interval)) is correct, although I<br>
think we should add '1' to the interval to account for sampling phase<br>
errors in the monotonic clock. As that's measured in ns, and I'm<br>
currently getting values in the µs range, that's a small error in<br>
comparison.<br></blockquote><div><br></div><div>You've got me almost convinced as well.  Thanks for the diagrams!  I think instead of adding 1 perhaps what we want is</div><div><br></div><div>max2(sample_interval_ns, gpu_tick_ns + monotonic_tick_ns)</div><div><br></div><div>Where monotonic_tick_ns is maybe as low as 1.  Am I following you correctly?<br></div><div><br></div><div>--Jason<br></div></div></div>