Hi all
I would like some GUI elements in a patch to refresh with the highest rate possible, but at the same time also as economic (in terms of CPU usage) as possible.
How can I know at which rate a Pd canvas is updated so that I can adjust the gui update accordingly?
Matju directed me to the respective parts in the source code, but I was not able to make any sense out of it.
I've come so far yet: In src/m_sched there is 'void sched_tick' which (afaict) runs the 'while' loop that runs the whole Pd DSP and GUI stuff. It seems that every 5000 clock ticks, the whole GUI is refreshed (sys_pollgui()). But how long is such a tick? Can someone make more sense out of it?
Roman
Le 2011-11-17 à 15:18:00, Roman Haefeli a écrit :
Matju directed me to the respective parts in the source code, but I was not able to make any sense out of it.
I said something wrong near the end because I spoke too quick. sched_tick is not a main loop, it's the common part between the big mainloop (ordinary mode), the short mainloop (-batch) and the big callback (-schedlib).
The top of that file defines :
#define TIMEUNITPERSEC (32.*441000.)
which is used by users of sched_tick.
That's 14112000 or pow(2,8)*pow(3,2)*pow(5,3)*pow(7,2).
44100 is pow(2,2)*pow(3,2)*pow(5,2)*pow(7,2).
48000 is pow(2,7)*pow(3,1)*pow(5,0)*pow(7,0).
Miller's idea was to have a fixed unit in which samples of both a 44100 Hz and a 48000 Hz stream correspond to whole numbers in that scale.
the lcm (aka ppcm or least common denominator) of 44100 and 48000 is half of TIMEUNITPERSEC. The last doubling is to also support doubled sampling rates like 88200 and 96000, even though people don't have the corresponding set of ears.
I split TIMEUNITPERSEC in prime factors because that's a good way to see common denominators. The other way is Euclid's method.
I doubt that the choice of TIMEUNITPERSEC makes that much of a practical difference though... unless the intent is to prevent drifting of the clock, but even careless counting is already lots more precise than some soundcards for which the sampling rate is just a suggestion...
In my first Pd years, I had a soundcard running at 44098 Hz on one of my computers.
| Mathieu BOUCHARD ----- téléphone : +1.514.383.3801 ----- Montréal, QC
On Thu, 2011-11-17 at 10:58 -0500, Mathieu Bouchard wrote:
Le 2011-11-17 à 15:18:00, Roman Haefeli a écrit :
Matju directed me to the respective parts in the source code, but I was not able to make any sense out of it.
I said something wrong near the end because I spoke too quick. sched_tick is not a main loop, it's the common part between the big mainloop (ordinary mode), the short mainloop (-batch) and the big callback (-schedlib).
The top of that file defines :
#define TIMEUNITPERSEC (32.*441000.)
which is used by users of sched_tick.
That's 14112000 or pow(2,8)*pow(3,2)*pow(5,3)*pow(7,2).
44100 is pow(2,2)*pow(3,2)*pow(5,2)*pow(7,2).
48000 is pow(2,7)*pow(3,1)*pow(5,0)*pow(7,0).
Ah.. I was actually looking for the number 14112000, but of course I didn't look for 32. * 441000.
But then, 14112000 / 5000 gives 2822.4 Hz, which would be a too high rate for GUI refresh. So, what is relation between the tick and 5000 that leads to a sane GUI refresh rate (and finally, what _is_ the GUI refresh rate)?
Roman
Le 2011-11-18 à 09:34:00, Roman Haefeli a écrit :
Ah.. I was actually looking for the number 14112000, but of course I didn't look for 32. * 441000. But then, 14112000 / 5000 gives 2822.4 Hz, which would be a too high rate for GUI refresh. So, what is relation between the tick and 5000 that leads to a sane GUI refresh rate (and finally, what _is_ the GUI refresh rate)?
Oops !
sched_tick handles the span of time of one hardware dsp block, and I think that this is usually frozen to be 64 samples regardless of sampling rate (for 44100 Hz, this is 1.45 ms). the while() loop looks for all upcoming clock events ([metro], [delay], [pipe], etc) and processes them until the time of the next dsp block.
The 5000 might be never used. You'd need 5000 [metro] or [delay] objects being activated between two consecutive dsp blocks. In addition to being very unlikely, it's also nearly impossible to do : if 5000 objects put 5000 things in the clock queue in chronological order, this takes 12.5 million loops per clock tick, and each loop is 3 comparisons and 2 assignments. No CPU has the time to do it in one tick. Pd doesn't have to be like that, there are good datastructures that it could use, but it does not use them, so it's extremely inefficient at some things when those things appear in large numbers.
You can get well over 5000 clock activations in one dsp tick, but you have to do it in other ways. you need a self-connected [delay] with an extremely low number, because [metro] won't let you make a [metro] that fast.
Anyway, I don't get it, I mean I don't get the existence of the 5000. My previous answer about 14112000 was a mistake : the number is correct but unrelated.
Instead, sys_pollgui is called almost only from m_pollingscheduler...
It looks like it's called at every dsp tick (1.45 ms) but inside sys_pollgui it calls sys_domicrosleep which is actually a function that checks all filehandles for incoming data, and if there's no incoming data in a given tick, then sys_poll_togui is called. That one, in turn, checks whether the output buffer is empty, and if it isn't, then it doesn't call sys_flushqueue.
So, the answer seems like it's that pd refreshes the gui using a clock of 689 Hz, and the fastest possible GUI updates would be half of that, but Tcl never keeps up with that, so it slows down the rate by just not reading enough stuff that pd sends it, and pd skips calls to sys_flushqueue in those cases.
| Mathieu BOUCHARD ----- téléphone : +1.514.383.3801 ----- Montréal, QC
There's no fixed update rate, but Mahieu is right, Pd polls for the ability to make an update every DSP tick. (one is able to do an update if the socket from Pd to GUI is writable, i.e., not full).
I've thought for a long time about putting an explicit throttle (on the order of 5-10 msec) or a flow control mechanism (passing round-trip tokens through the GUI to see when things are actually getting updated) but have put this off because of more urgent problems :)
M
On Fri, Nov 18, 2011 at 11:48:25AM -0500, Mathieu Bouchard wrote:
Le 2011-11-18 à 09:34:00, Roman Haefeli a écrit :
Ah.. I was actually looking for the number 14112000, but of course I didn't look for 32. * 441000. But then, 14112000 / 5000 gives 2822.4 Hz, which would be a too high rate for GUI refresh. So, what is relation between the tick and 5000 that leads to a sane GUI refresh rate (and finally, what _is_ the GUI refresh rate)?
Oops !
sched_tick handles the span of time of one hardware dsp block, and I think that this is usually frozen to be 64 samples regardless of sampling rate (for 44100 Hz, this is 1.45 ms). the while() loop looks for all upcoming clock events ([metro], [delay], [pipe], etc) and processes them until the time of the next dsp block.
The 5000 might be never used. You'd need 5000 [metro] or [delay] objects being activated between two consecutive dsp blocks. In addition to being very unlikely, it's also nearly impossible to do : if 5000 objects put 5000 things in the clock queue in chronological order, this takes 12.5 million loops per clock tick, and each loop is 3 comparisons and 2 assignments. No CPU has the time to do it in one tick. Pd doesn't have to be like that, there are good datastructures that it could use, but it does not use them, so it's extremely inefficient at some things when those things appear in large numbers.
You can get well over 5000 clock activations in one dsp tick, but you have to do it in other ways. you need a self-connected [delay] with an extremely low number, because [metro] won't let you make a [metro] that fast.
Anyway, I don't get it, I mean I don't get the existence of the 5000. My previous answer about 14112000 was a mistake : the number is correct but unrelated.
Instead, sys_pollgui is called almost only from m_pollingscheduler...
It looks like it's called at every dsp tick (1.45 ms) but inside sys_pollgui it calls sys_domicrosleep which is actually a function that checks all filehandles for incoming data, and if there's no incoming data in a given tick, then sys_poll_togui is called. That one, in turn, checks whether the output buffer is empty, and if it isn't, then it doesn't call sys_flushqueue.
So, the answer seems like it's that pd refreshes the gui using a clock of 689 Hz, and the fastest possible GUI updates would be half of that, but Tcl never keeps up with that, so it slows down the rate by just not reading enough stuff that pd sends it, and pd skips calls to sys_flushqueue in those cases.
| Mathieu BOUCHARD ----- téléphone : +1.514.383.3801 ----- Montréal, QC
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Lame question: Would user-settable GUI refresh rate help with speed problems or with audio dropouts that some people experience? Or do these depend on the amount of data transmitted and not on the update frequency?
Andras
On Fri, Nov 18, 2011 at 18:41, Miller Puckette msp@ucsd.edu wrote:
There's no fixed update rate, but Mahieu is right, Pd polls for the ability to make an update every DSP tick. (one is able to do an update if the socket from Pd to GUI is writable, i.e., not full).
I've thought for a long time about putting an explicit throttle (on the order of 5-10 msec) or a flow control mechanism (passing round-trip tokens through the GUI to see when things are actually getting updated) but have put this off because of more urgent problems :)
M
On Fri, Nov 18, 2011 at 11:48:25AM -0500, Mathieu Bouchard wrote:
Le 2011-11-18 à 09:34:00, Roman Haefeli a écrit :
Ah.. I was actually looking for the number 14112000, but of course I didn't look for 32. * 441000. But then, 14112000 / 5000 gives 2822.4 Hz, which would be a too high rate for GUI refresh. So, what is relation between the tick and 5000 that leads to a sane GUI refresh rate (and finally, what _is_ the GUI refresh rate)?
Oops !
sched_tick handles the span of time of one hardware dsp block, and I think that this is usually frozen to be 64 samples regardless of sampling rate (for 44100 Hz, this is 1.45 ms). the while() loop looks for all upcoming clock events ([metro], [delay], [pipe], etc) and processes them until the time of the next dsp block.
The 5000 might be never used. You'd need 5000 [metro] or [delay] objects being activated between two consecutive dsp blocks. In addition to being very unlikely, it's also nearly impossible to do : if 5000 objects put 5000 things in the clock queue in chronological order, this takes 12.5 million loops per clock tick, and each loop is 3 comparisons and 2 assignments. No CPU has the time to do it in one tick. Pd doesn't have to be like that, there are good datastructures that it could use, but it does not use them, so it's extremely inefficient at some things when those things appear in large numbers.
You can get well over 5000 clock activations in one dsp tick, but you have to do it in other ways. you need a self-connected [delay] with an extremely low number, because [metro] won't let you make a [metro] that fast.
Anyway, I don't get it, I mean I don't get the existence of the 5000. My previous answer about 14112000 was a mistake : the number is correct but unrelated.
Instead, sys_pollgui is called almost only from m_pollingscheduler...
It looks like it's called at every dsp tick (1.45 ms) but inside sys_pollgui it calls sys_domicrosleep which is actually a function that checks all filehandles for incoming data, and if there's no incoming data in a given tick, then sys_poll_togui is called. That one, in turn, checks whether the output buffer is empty, and if it isn't, then it doesn't call sys_flushqueue.
So, the answer seems like it's that pd refreshes the gui using a clock of 689 Hz, and the fastest possible GUI updates would be half of that, but Tcl never keeps up with that, so it slows down the rate by just not reading enough stuff that pd sends it, and pd skips calls to sys_flushqueue in those cases.
| Mathieu BOUCHARD ----- téléphone : +1.514.383.3801 ----- Montréal, QC
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management ->
http://lists.puredata.info/listinfo/pd-list
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
On Fri, 2011-11-18 at 18:53 +0100, András Murányi wrote:
Lame question: Would user-settable GUI refresh rate help with speed problems or with audio dropouts that some people experience? Or do these depend on the amount of data transmitted and not on the update frequency?
I _think_ this depends on the kind of GUI element. If you send thousand messages per second to a slider, then it would probably help. But you can limit the rate already now, so I personally don't think that a fixed refresh rate would urgently be necessary.
I think arrays can be quite a hog since not only for every pixel you see a message from pd to pd-gui was sent, but for every sample. This can be quite a lot of messages when you change significant chunks of an array. However, a fixed GUI refresh rate wouldn't help with this.
Roman
----- Original Message -----
From: Roman Haefeli reduzent@gmail.com To: pd-list@iem.at Cc: Sent: Friday, November 18, 2011 3:10 PM Subject: Re: [PD] pd-gui update rate
On Fri, 2011-11-18 at 18:53 +0100, András Murányi wrote:
Lame question: Would user-settable GUI refresh rate help with speed problems or with audio dropouts that some people experience? Or do these depend on the amount of data transmitted and not on the update frequency?
I _think_ this depends on the kind of GUI element. If you send thousand messages per second to a slider, then it would probably help. But you can limit the rate already now, so I personally don't think that a fixed refresh rate would urgently be necessary.
I think arrays can be quite a hog since not only for every pixel you see a message from pd to pd-gui was sent, but for every sample. This can be quite a lot of messages when you change significant chunks of an array.
You don't even have to change the array-- just displace it in edit mode. If I remember correctly, for every pixel it's displaced pd recalculates the relationship between pixels and samples to redraw the array, rather than just moving in Tk by tag. It's ridiculous.
-Jonathan
However, a fixed GUI refresh rate wouldn't help with this.
Roman
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
One thing that would be very nice is if pd-gui checked the OS for the current screen refresh rate, and then used that as the clock for refreshing the GUI. Seems quite feasible to me. But actually, now that I think about it, I am sure that any decent GUI toolkit does this already, so really it seems that we should be offloading as much as possible to the GUI toolkit and have 'pd' itself speak on a higher level, e.g.:
draw this object here, tell me if it was clicked"
versus the current:
draw these lines for the box, draw these lines for the inlets and outlets, draw this text, and check to see if the mouse is above this box or clicked on it so I can tell it to change its appearance
.hc
On Nov 18, 2011, at 12:41 PM, Miller Puckette wrote:
There's no fixed update rate, but Mahieu is right, Pd polls for the ability to make an update every DSP tick. (one is able to do an update if the socket from Pd to GUI is writable, i.e., not full).
I've thought for a long time about putting an explicit throttle (on the order of 5-10 msec) or a flow control mechanism (passing round-trip tokens through the GUI to see when things are actually getting updated) but have put this off because of more urgent problems :)
M
On Fri, Nov 18, 2011 at 11:48:25AM -0500, Mathieu Bouchard wrote:
Le 2011-11-18 à 09:34:00, Roman Haefeli a écrit :
Ah.. I was actually looking for the number 14112000, but of course I didn't look for 32. * 441000. But then, 14112000 / 5000 gives 2822.4 Hz, which would be a too high rate for GUI refresh. So, what is relation between the tick and 5000 that leads to a sane GUI refresh rate (and finally, what _is_ the GUI refresh rate)?
Oops !
sched_tick handles the span of time of one hardware dsp block, and I think that this is usually frozen to be 64 samples regardless of sampling rate (for 44100 Hz, this is 1.45 ms). the while() loop looks for all upcoming clock events ([metro], [delay], [pipe], etc) and processes them until the time of the next dsp block.
The 5000 might be never used. You'd need 5000 [metro] or [delay] objects being activated between two consecutive dsp blocks. In addition to being very unlikely, it's also nearly impossible to do : if 5000 objects put 5000 things in the clock queue in chronological order, this takes 12.5 million loops per clock tick, and each loop is 3 comparisons and 2 assignments. No CPU has the time to do it in one tick. Pd doesn't have to be like that, there are good datastructures that it could use, but it does not use them, so it's extremely inefficient at some things when those things appear in large numbers.
You can get well over 5000 clock activations in one dsp tick, but you have to do it in other ways. you need a self-connected [delay] with an extremely low number, because [metro] won't let you make a [metro] that fast.
Anyway, I don't get it, I mean I don't get the existence of the 5000. My previous answer about 14112000 was a mistake : the number is correct but unrelated.
Instead, sys_pollgui is called almost only from m_pollingscheduler...
It looks like it's called at every dsp tick (1.45 ms) but inside sys_pollgui it calls sys_domicrosleep which is actually a function that checks all filehandles for incoming data, and if there's no incoming data in a given tick, then sys_poll_togui is called. That one, in turn, checks whether the output buffer is empty, and if it isn't, then it doesn't call sys_flushqueue.
So, the answer seems like it's that pd refreshes the gui using a clock of 689 Hz, and the fastest possible GUI updates would be half of that, but Tcl never keeps up with that, so it slows down the rate by just not reading enough stuff that pd sends it, and pd skips calls to sys_flushqueue in those cases.
| Mathieu BOUCHARD ----- téléphone : +1.514.383.3801 ----- Montréal, QC
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Computer science is no more related to the computer than astronomy is related to the telescope. -Edsger Dykstra
Hi
Thanks to Charles, Matju and Miller for your answers.
It's somewhat clearer now how those things are working together. In the meanwhile, I made some test. I figured I'd probably be able to determine the refresh rate myself with the help of the nyquist theorem. I made a patch that lets the background color of an iemgui flicker between black and white at a settable rate. Assuming that when I hit twice the Nyquist frequency of the refresh rate (which equals the refresh rate) the visible flicker frequency should go towards zero, which means the slider should stay black or white. Apparently, this happens when I set the [metro] to 8.33333 ms. The actual period is twice that, because I need a metro tick for the white and one for the black phase. So the whole period amounts to 16.6666ms which corresponds to 60 Hz, which is the refresh rate of my screen.
Somehow I was always assuming that Tk (at least in Pd) is rendering slower than that. Don't know why I believed in that myth. Actually, I like being able to use the full speed of my screen in Pd. Yet, in many patches I often artificially limited GUI refreshs to 20 Hz, assuming that higher rates wouldn't be displayed anyway. Wrong!
Thanks! Roman
On Fri, 2011-11-18 at 09:41 -0800, Miller Puckette wrote:
There's no fixed update rate, but Mahieu is right, Pd polls for the ability to make an update every DSP tick. (one is able to do an update if the socket from Pd to GUI is writable, i.e., not full).
I've thought for a long time about putting an explicit throttle (on the order of 5-10 msec) or a flow control mechanism (passing round-trip tokens through the GUI to see when things are actually getting updated) but have put this off because of more urgent problems :)
M
On Fri, Nov 18, 2011 at 11:48:25AM -0500, Mathieu Bouchard wrote:
Le 2011-11-18 à 09:34:00, Roman Haefeli a écrit :
Ah.. I was actually looking for the number 14112000, but of course I didn't look for 32. * 441000. But then, 14112000 / 5000 gives 2822.4 Hz, which would be a too high rate for GUI refresh. So, what is relation between the tick and 5000 that leads to a sane GUI refresh rate (and finally, what _is_ the GUI refresh rate)?
Oops !
sched_tick handles the span of time of one hardware dsp block, and I think that this is usually frozen to be 64 samples regardless of sampling rate (for 44100 Hz, this is 1.45 ms). the while() loop looks for all upcoming clock events ([metro], [delay], [pipe], etc) and processes them until the time of the next dsp block.
The 5000 might be never used. You'd need 5000 [metro] or [delay] objects being activated between two consecutive dsp blocks. In addition to being very unlikely, it's also nearly impossible to do : if 5000 objects put 5000 things in the clock queue in chronological order, this takes 12.5 million loops per clock tick, and each loop is 3 comparisons and 2 assignments. No CPU has the time to do it in one tick. Pd doesn't have to be like that, there are good datastructures that it could use, but it does not use them, so it's extremely inefficient at some things when those things appear in large numbers.
You can get well over 5000 clock activations in one dsp tick, but you have to do it in other ways. you need a self-connected [delay] with an extremely low number, because [metro] won't let you make a [metro] that fast.
Anyway, I don't get it, I mean I don't get the existence of the 5000. My previous answer about 14112000 was a mistake : the number is correct but unrelated.
Instead, sys_pollgui is called almost only from m_pollingscheduler...
It looks like it's called at every dsp tick (1.45 ms) but inside sys_pollgui it calls sys_domicrosleep which is actually a function that checks all filehandles for incoming data, and if there's no incoming data in a given tick, then sys_poll_togui is called. That one, in turn, checks whether the output buffer is empty, and if it isn't, then it doesn't call sys_flushqueue.
So, the answer seems like it's that pd refreshes the gui using a clock of 689 Hz, and the fastest possible GUI updates would be half of that, but Tcl never keeps up with that, so it slows down the rate by just not reading enough stuff that pd sends it, and pd skips calls to sys_flushqueue in those cases.
| Mathieu BOUCHARD ----- téléphone : +1.514.383.3801 ----- Montréal, QC
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list