-
Notifications
You must be signed in to change notification settings - Fork 315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Query API: Timestamp Query #771
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM overall
@RafaelCintron @litherum @kvark please take a look! |
@annevk pointed out that we might need to say a few words about the resolution of the timing here. More specifically, it will be subject to cross-origin policy and generally not exceed the resolution of I'm fine with following up with that, given that the security consideration section will also need to be adjusted. |
Timestamps should have no link with COOP or COEP. Or do you mean that you want timestamps to only be available when the page is COOP + COEP? My understanding is that SharedArrayBuffer is gated on it because of Specter / Metldown but there is no speculative execution on the GPU so that shouldn't matter. |
The concern is giving the page access to a high-resolution timer through the GPU. |
Timestamp queries give you high-resolution timers on the GPU but there significant roundtripping latency (that can easily vary in the millisecond range) between CPU and GPU so I don't think you'd be able to get any useful high-precision timer CPU timer. That said timestamp queries are mostly useful for development (for telemetry there is the GPUCommandBuffer timing that we discussed and isn't in the spec yet), so restricting to COOP + COEP or being devtools enabled could be fine. |
Even without the rountripping latency, I don't think there's a way to measure CPU time at all using timestamp queries. A timestamp query begins and ends in the same command buffer and measures only GPU-side work. It's not possible to do e.g.:
|
Sounds like this is mostly a non-concern, unless we start considering GPU precision timing to be an attack vector (as opposed to CPU precision timer). We can land the PR as is. |
Does that mean https://gpuweb.github.io/gpuweb/#security-timing needs changes as well? It also feels a little brittle to rely on the latency between the CPU and GPU. But yeah, this should probably be discussed separately. |
This definitely deserves a mention there, but like I explained I don't think we are actually relying on the latency between CPU and GPU. You've reminded me about what is written in that section already, also. We do know we still have to figure out if there will be restrictions on the use of WebGPU (especially on multiple threads) given what's written there about the equivalence with SAB. |
FWIW, what I was thinking about was more
|
I guess you could submit the commands writing to a timestamp and then asynchronously read them back. Each of the two submissions would involve multiple syscalls, IPC between the content process and the GPU process, so it doesn't seem to practical. What might be more practical is doing the same when software fallback is happening via Swiftshader since only the IPC calls are done. Maybe the timestamp feature could be force to disabled with Swiftshader. |
Oh, I was thinking about disjoint timer queries, where there are no timestamps, only time durations. I forgot our timestamp queries are not disjoint. Sorry for the confusion. |
Maybe we should consider disjoint timer queries to sidestep any high precision timer issue? |
Actually the timestamps returned to users will be a time delta processed by compute shader, the first timestamp will be 0 , the following values are the deltas based on the first one. But no matter how to return the results of timestamp query, they're in nanosecond. If we want to sidestep potential risks in high precision, how about define an internal timestamp period to increase nanosecond interval like Vulkan did (VkPhysicalDeviceLimits::timestampPeriod). |
Note that if a process that talks to the GPU is cross-origin isolated it should be fine for the timers to be as precise as can be (assuming the GPU cannot leak those to other processes that are not cross-origin isolated). And I think offering high-precision timers in cross-origin isolated cases is desirable as we do want to offer as much raw power as we can to those who isolate themselves. Hope that helps. |
This is similar to performance.now(), and it still returns timestamps, not time deltas. But yes, the timestamp values come from the GPU through the GPU process, so they're giving precise timing values for a different piece of hardware, through a different process and an IPC channel. I don't know exactly how much precision is needed (since timings can be amplified through multiple attempts), but the precision of a single timestamp would be very low (probably 0.25ms?). |
We've had good discussion about the potential risks of this API and mechanisms when it could be enabled, but there's been few comments on the shape of the API itself. It would be nice to get this landed if there are no more concerns about the shape. @kvark @litherum @JusSn do you have any comments on the API shape? We should definitely keep discussing the constraints on availability, but since this is an optional feature of WebGPU, I think if we choose to add any constraints it will be easy to do so. |
spec/index.bs
Outdated
|
||
|
||
## Timestamp Query ## {#timestamp} | ||
Timestamp query allows application to write timestamp values to a {{GPUQuerySet}} by calling {{GPUProgrammablePassEncoder/writeTimestamp()}} on render pass or compute pass, and then resolve timestamp values in **nanoseconds** (type of {{GPUSize64}}) to a {{GPUBuffer}} (using {{GPUCommandEncoder/resolveQuerySet()}}). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add an Issue
that points to this PR and explains that because the feature provides high-resolution GPU timestamps we need to decide what constraints, if any, are on its availability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Do we need to open an issue for further discussion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with the shape, especially since it's an optional extension.
We can talk about the resolution of the timestamp query and the availability of the extension separately.
Also, if we decide to move this out into a separate document, we can also do this later.
spec/index.bs
Outdated
@@ -3693,6 +3696,10 @@ interface mixin GPUProgrammablePassEncoder { | |||
void pushDebugGroup(USVString groupLabel); | |||
void popDebugGroup(); | |||
void insertDebugMarker(USVString markerLabel); | |||
|
|||
void beginPipelineStatisticsQuery(GPUQuerySet querySet, GPUSize32 queryIndex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we limit this PR to timestamp queries only?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is just a merge error; beginPipelineStatisticsQuery is already in master.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, beginPipelineStatisticsQuery
and endPipelineStatisticsQuery
have been changed in #797, this two lines should be added when git rebase, I will remove them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I forgot that timestamp query is also not supported on render bundle encoder, as same as pipeline statistics query, so we need to move writeTimestamp
to render encoder and compute encoder.
beginPipelineStatisticsQuery and endPipelineStatisticsQuery have been changed in gpuweb#797, remove them in GPUProgrammablePassEncoder which are added when rebasing.
Travis hiccupped; tested build locally and force merging. |
`maxStorageTexturesPerShaderStage` is `4` according to: https://www.w3.org/TR/webgpu/#dom-supported-limits-maxstoragetexturespershaderstage
Add extension and entrypoints for timestamp query according to #614.
Preview | Diff