Skip to main content
deleted 72 characters in body
Source Link

This is a very poor design even before the issues you mentioned came to light.

In order to make these queries asynchronous like they are supposed to be, you're expected to jam a fence into the command queue immediately following the issue of the end timestamp.

Now, evidently the temptation in this code snippet is to read the value of end immediately, but ... surprise, surprise, the GPU has not even started working on your frame yet and waiting on the result is going to sit and spin while 2-4 or more frames go through the render pipeline and the GPU finally gives you a timestamp counter that you can readback, meanwhile the CPU was blocking the whole time and now the GPU has no render-ahead command queue; stutter ensues and now the act of measuring performance is hurting it.

If you do manage to read something back without waiting, the results are going to be undefined.

You are killing CPU/GPU parallelism and more than likely don't want performance measurements taken while the render pipeline is in duress.

This is why your code is full of horrible flush / finish commands. Stop doing that and use a fence sync object instead. Once per-frame check the status of the fence you planted after your timestamp query. If the fence is signaled, now you can readback the timer query with no ill-effects.

The GL, of course, has a way of checking whether queries are ready, but this is how that check is more or less implemented and other APIs basically require you to put fences in the command stream to figure out whether a command is retired yet or not, so it's handy to learn.

This most likely doesn't answer your question, however, if you're willingly waiting on something to finish that's generated through pipelined execution there's no telling what else is wrong with your software. I'd do a quick survey of all read-back sites and try to develop any code using those readbacks the ability to tolerate 3-4 frames of latency.

This is a very poor design even before the issues you mentioned came to light.

In order to make these queries asynchronous like they are supposed to be, you're expected to jam a fence into the command queue immediately following the issue of the end timestamp.

Now, evidently the temptation in this code snippet is to read the value of end immediately, but ... surprise, surprise, the GPU has not even started working on your frame yet and waiting on the result is going to sit and spin while 2-4 or more frames go through the render pipeline and the GPU finally gives you a timestamp counter that you can readback, meanwhile the CPU was blocking the whole time and now the GPU has no render-ahead command queue; stutter ensues and now the act of measuring performance is hurting it.

You are killing CPU/GPU parallelism and more than likely don't want performance measurements taken while the render pipeline is in duress.

This is why your code is full of horrible flush / finish commands. Stop doing that and use a fence sync object instead. Once per-frame check the status of the fence you planted after your timestamp query. If the fence is signaled, now you can readback the timer query with no ill-effects.

The GL, of course, has a way of checking whether queries are ready, but this is how that check is more or less implemented and other APIs basically require you to put fences in the command stream to figure out whether a command is retired yet or not, so it's handy to learn.

This most likely doesn't answer your question, however, if you're willingly waiting on something to finish that's generated through pipelined execution there's no telling what else is wrong with your software. I'd do a quick survey of all read-back sites and try to develop any code using those readbacks the ability to tolerate 3-4 frames of latency.

This is a very poor design even before the issues you mentioned came to light.

In order to make these queries asynchronous like they are supposed to be, you're expected to jam a fence into the command queue immediately following the issue of the end timestamp.

Now, evidently the temptation in this code snippet is to read the value of end immediately, but ... surprise, surprise, the GPU has not even started working on your frame yet and waiting on the result is going to sit and spin while 2-4 or more frames go through the render pipeline and the GPU finally gives you a timestamp counter that you can readback.

If you do manage to read something back without waiting, the results are going to be undefined.

You are killing CPU/GPU parallelism and more than likely don't want performance measurements taken while the render pipeline is in duress.

This is why your code is full of horrible flush / finish commands. Stop doing that and use a fence sync object instead. Once per-frame check the status of the fence you planted after your timestamp query. If the fence is signaled, now you can readback the timer query with no ill-effects.

The GL, of course, has a way of checking whether queries are ready, but this is how that check is more or less implemented and other APIs basically require you to put fences in the command stream to figure out whether a command is retired yet or not, so it's handy to learn.

This most likely doesn't answer your question, however, if you're willingly waiting on something to finish that's generated through pipelined execution there's no telling what else is wrong with your software. I'd do a quick survey of all read-back sites and try to develop any code using those readbacks the ability to tolerate 3-4 frames of latency.

Source Link

This is a very poor design even before the issues you mentioned came to light.

In order to make these queries asynchronous like they are supposed to be, you're expected to jam a fence into the command queue immediately following the issue of the end timestamp.

Now, evidently the temptation in this code snippet is to read the value of end immediately, but ... surprise, surprise, the GPU has not even started working on your frame yet and waiting on the result is going to sit and spin while 2-4 or more frames go through the render pipeline and the GPU finally gives you a timestamp counter that you can readback, meanwhile the CPU was blocking the whole time and now the GPU has no render-ahead command queue; stutter ensues and now the act of measuring performance is hurting it.

You are killing CPU/GPU parallelism and more than likely don't want performance measurements taken while the render pipeline is in duress.

This is why your code is full of horrible flush / finish commands. Stop doing that and use a fence sync object instead. Once per-frame check the status of the fence you planted after your timestamp query. If the fence is signaled, now you can readback the timer query with no ill-effects.

The GL, of course, has a way of checking whether queries are ready, but this is how that check is more or less implemented and other APIs basically require you to put fences in the command stream to figure out whether a command is retired yet or not, so it's handy to learn.

This most likely doesn't answer your question, however, if you're willingly waiting on something to finish that's generated through pipelined execution there's no telling what else is wrong with your software. I'd do a quick survey of all read-back sites and try to develop any code using those readbacks the ability to tolerate 3-4 frames of latency.