Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-11-23 Thread William Huston
Got it. Thanks.

On Mon, Nov 23, 2015 at 2:47 PM, IOhannes m zmölnig  wrote:

> On 11/23/2015 07:56 PM, William Huston wrote:
> >> what qualifies as a "complex orphaned network"?
> [...]
> >
> > A tilde object is "active" (not orphaned) when its output is connected to
> > any object which stores computed audio in memory, or sends audio
> > external to PD,  like [dac~], [tabwrite~], or [writesf~].
> >
> > (OK-- externals become tricky, as PD's DSP compiler needs to understand
> > wither the external object sends audio outside PD, such as across
> > a network, or stores audio in memory)
>
> (does [hip~] store audio in memory?)
>
> how is Pd supposed to know "this"?
>
> the problem with all this is, that the entire scheme for saving CPU
> cycles will be screwed if you there is a single object in your
> to-be-orphaned network of which you don't know whether it has
> "side-effects" (as in I/O; but also any other side-effect) or not.
>
> > A [throw~] / [catch~] network is orphaned if the output of [catch~]
> > is connected to an orphaned tilde network.
> >
> > These kinds of orphans (at least for PD vanilla objects)
> > should be easy to detect
>
> since Pd allows an external to override built-in classes, you don't even
> know whether a sole unconnected [osc~] object does not phone home.
>
> (though you probably can still find out whether any given object is
> constructed from an external or "built-in")
>
> in any case, the suggestion boils down to maintaining a "whitelist" of
> objects-without-sideeffects, which is fragile at best.
>
> > I want to understand whether orphaned tilde objects are part of
> > the DSP graph, and steal cycles? or are they harmless?
>
> yes. no (not in your sense).
>
> if you are concerened about orphaned objects stealing CPU cycles, delete
> them from your patch. this way they are *guaranteed* to not take any CPU
> (nor memory), even with the most naive scheduler.
> also: Pd has [switch~] to turn off parts of a DSP-graph (even if it is
> not orphaned!).
>
> gfmadsr
> IOhannes
>
>
> ___
> Pd-list@lists.iem.at mailing list
> UNSUBSCRIBE and account-management ->
> http://lists.puredata.info/listinfo/pd-list
>
>


-- 
--
May you, and all beings
be happy and free from suffering :)
-- ancient Buddhist Prayer (Metta)
___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list


Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-11-23 Thread IOhannes m zmölnig
On 11/23/2015 07:56 PM, William Huston wrote:
>> what qualifies as a "complex orphaned network"?
[...]
> 
> A tilde object is "active" (not orphaned) when its output is connected to
> any object which stores computed audio in memory, or sends audio
> external to PD,  like [dac~], [tabwrite~], or [writesf~].
> 
> (OK-- externals become tricky, as PD's DSP compiler needs to understand
> wither the external object sends audio outside PD, such as across
> a network, or stores audio in memory)

(does [hip~] store audio in memory?)

how is Pd supposed to know "this"?

the problem with all this is, that the entire scheme for saving CPU
cycles will be screwed if you there is a single object in your
to-be-orphaned network of which you don't know whether it has
"side-effects" (as in I/O; but also any other side-effect) or not.

> A [throw~] / [catch~] network is orphaned if the output of [catch~]
> is connected to an orphaned tilde network.
> 
> These kinds of orphans (at least for PD vanilla objects)
> should be easy to detect 

since Pd allows an external to override built-in classes, you don't even
know whether a sole unconnected [osc~] object does not phone home.

(though you probably can still find out whether any given object is
constructed from an external or "built-in")

in any case, the suggestion boils down to maintaining a "whitelist" of
objects-without-sideeffects, which is fragile at best.

> I want to understand whether orphaned tilde objects are part of
> the DSP graph, and steal cycles? or are they harmless?

yes. no (not in your sense).

if you are concerened about orphaned objects stealing CPU cycles, delete
them from your patch. this way they are *guaranteed* to not take any CPU
(nor memory), even with the most naive scheduler.
also: Pd has [switch~] to turn off parts of a DSP-graph (even if it is
not orphaned!).

gfmadsr
IOhannes



signature.asc
Description: OpenPGP digital signature
___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list


Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-11-23 Thread Jonathan Wilkes via Pd-list
Hi William,In practice, I'm not sure how inefficient they are.  Pd already has 
[switch~] for situations where some 
subpatch doesn't need to compute audio.
-Jonathan
   

 On Monday, November 23, 2015 1:58 PM, William Huston 
 wrote:
 

 > what qualifies as a "complex orphaned network"?

and [osc~] with no wires is the most trivial example of an 
orphaned tilde object. There is no need to add  it to the
DSP graph or compute audio for such. 

An orphaned (tilde) network is created when I connect two orphaned 
tilde objects together.

> how do you determine whether a dsp-object has I/O?

A tilde object is "active" (not orphaned) when its output is connected to 
any object which stores computed audio in memory, or sends audio 
external to PD,  like [dac~], [tabwrite~], or [writesf~].  

(OK-- externals become tricky, as PD's DSP compiler needs to understand
wither the external object sends audio outside PD, such as across
a network, or stores audio in memory)

A [throw~] / [catch~] network is orphaned if the output of [catch~]
is connected to an orphaned tilde network. 

These kinds of orphans (at least for PD vanilla objects) 
should be easy to detect if it is true as Jonathan says,
that there is a single DSP graph for each running instance of PD,
since they can be determined by examining the netlist alone. 
The reason I'm asking this is because since moving to a Raspberry Pi-based 
setup,
I'm trying to optimize my code for performance, since there is definitely a 
CPU budget on a Pi which is easily exceeded. 

I want to understand whether orphaned tilde objects are part of
the DSP graph, and steal cycles? or are they harmless? 



On Mon, Nov 23, 2015 at 1:18 PM, IOhannes m zmölnig  wrote:

On 11/23/2015 06:31 PM, William Huston wrote:
>
> *What about a complex "orphaned network" containing various tilde objects?*
>

what qualifies as a "complex orphaned network"?
how do you determine whether a dsp-object has I/O?


mfds
IOhannes


___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list





-- 
--
May you, and all beings
be happy and free from suffering :)
-- ancient Buddhist Prayer (Metta)

___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list


  ___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list


Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-11-23 Thread William Huston
> what qualifies as a "complex orphaned network"?

and [osc~] with no wires is the most trivial example of an
orphaned tilde object. There is no need to add  it to the
DSP graph or compute audio for such.

An orphaned (tilde) network is created when I connect two orphaned
tilde objects together.

> how do you determine whether a dsp-object has I/O?

A tilde object is "active" (not orphaned) when its output is connected to
any object which stores computed audio in memory, or sends audio
external to PD,  like [dac~], [tabwrite~], or [writesf~].

(OK-- externals become tricky, as PD's DSP compiler needs to understand
wither the external object sends audio outside PD, such as across
a network, or stores audio in memory)

A [throw~] / [catch~] network is orphaned if the output of [catch~]
is connected to an orphaned tilde network.

These kinds of orphans (at least for PD vanilla objects)
should be easy to detect if it is true as Jonathan says,
that there is a single DSP graph for each running instance of PD,
since they can be determined by examining the netlist alone.

The reason I'm asking this is because since moving to a Raspberry Pi-based
setup,
I'm trying to optimize my code for performance, since there is definitely a
CPU budget on a Pi which is easily exceeded.

I want to understand whether orphaned tilde objects are part of
the DSP graph, and steal cycles? or are they harmless?



On Mon, Nov 23, 2015 at 1:18 PM, IOhannes m zmölnig  wrote:

> On 11/23/2015 06:31 PM, William Huston wrote:
> >
> > *What about a complex "orphaned network" containing various tilde
> objects?*
> >
>
> what qualifies as a "complex orphaned network"?
> how do you determine whether a dsp-object has I/O?
>
>
> mfds
> IOhannes
>
>
> ___
> Pd-list@lists.iem.at mailing list
> UNSUBSCRIBE and account-management ->
> http://lists.puredata.info/listinfo/pd-list
>
>


-- 
--
May you, and all beings
be happy and free from suffering :)
-- ancient Buddhist Prayer (Metta)
___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list


Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-11-23 Thread IOhannes m zmölnig
On 11/23/2015 06:31 PM, William Huston wrote:
> 
> *What about a complex "orphaned network" containing various tilde objects?*
> 

what qualifies as a "complex orphaned network"?
how do you determine whether a dsp-object has I/O?


mfds
IOhannes



signature.asc
Description: OpenPGP digital signature
___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list


Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-11-23 Thread William Huston
This is an enormously helpful discussion.
Just reading it in-depth now.
I think this should be summarized for inclusion into an FAQ.

I have some circuit design experience (many years ago).
I worked with netlists for Spice and other circuit simulators.

My first big program in C (1989?) was a program which
traversed a Spice deck (a linked list) and among other things,
found "orphaned networks" which didn't go anywhere.
It's a network which ultimately has no input and no outputs.

There is no need to electrically simulate such orphans
(this was in the 1980s when computers were mainframes
and time was really expensive), and there is no need to
make these into silicon. So such circuits are "optimized out"
(deleted.)




*My question is, does PD compute audio for an orphaned [osc~] with no
leads?*

*What about a complex "orphaned network" containing various tilde objects?*

*Are these computed? Or optimized out during compilation?*

What I've heard here from Jonathan is,
"adding any tilde object recreates the DSP graph".

So just placing an [osc~] with no wires recalculates the graph?
The would seem like a waste.

Furthermore-- this can even be improved. If I take an [osc~] and connect
a wire to an object which is part of an active DSP graph (not orphaned),
then we clearly need to recompile.

However, if I connect the [osc~] to an "orphaned network" (no I/O),
then this does not need to recompile the graph.

I imagine there must be a PD agent which looks at the objects you've just
instantiated
and decides whether the DSP graph should be recompiled.

Is there any room for improvement here?

Thanks,
BH





On Tue, Sep 22, 2015 at 11:19 PM, Jonathan Wilkes via Pd-list <
pd-list@lists.iem.at> wrote:

> Does [soundfiler] rebuild the dsp graph on read, or only if the -resize
> flag
> is used?  If its the latter then you can just set the right array size
> ahead of time.
> Then if you still get dropouts you'll know it's the blocking i/o doing it.
>
> -Jonathan
>
>
>
> On Tuesday, September 22, 2015 10:50 PM, Matt Barber 
> wrote:
>
>
> There's nothing wrong per se with resizing an array -- but there are good
> reasons not to do it while a patch is running after a [tab*] object has
> referred to it. I have myself only noticed audio dropouts when I'm resizing
> a table with soundfiler; I thought it must have been a disk-access
> bottleneck (soundfiler runs synchronously, yes?), but it would make sense
> if it in very large patches that a resize triggering a DSP recalc could do
> it. Though, then wouldn't adding any tilde object do the same?
>
> On Tue, Sep 22, 2015 at 4:00 PM, Jonathan Wilkes via Pd-list <
> pd-list@lists.iem.at> wrote:
>
> In C, what's the overhead of having function_call(return array->x_size)
> instead
> of array->x_size inside a perform routine?
>
> If that's not significant, it seems like it'd be better to over-allocate
> the array at creation/resize time and report the requested size to the
> user.  That way reallocation (and dsp-rebuilding) is only necessary if
> there's a substantial size change, or if the array is used by an external
> that uses the old API.
>
> That's certainly more difficult to do than just rebuilding the graph on
> every resizing.  But to me it's preferable to telling new users, "Here's how
> to resize an array, which is a central feature for using objects like
> [tabplay~] and
> 'Put' menu arrays and [soundfiler], but in reality don't use it because
> [[explanation of Pd's implementation details go here]]."
>
> -Jonathan
>
>
> On Tuesday, September 22, 2015 12:05 PM, Roman Haefeli 
> wrote:
>
>
> On Sun, 2015-09-20 at 22:19 +0200, IOhannes m zmölnig wrote:
> > On 09/17/2015 11:55 PM, Roman Haefeli wrote:
> >
> > > Is the time it takes to recalculate the graph only dependent on the
> > > number of tilde-objects running in the current instance of Pd? If so,
> is
> > > that a linear correlation? 10 times more tilde-objects means it takes
> 10
> > > times as long to recalculate the graph?
> >
> > [skipping those]
>
> Simple tests suggests that the relation is linear. But maybe this
> depends on the kind of graph? What I tested: I created 500 audio
> processing abstractions dynamically and then I measured the time it
> takes to send 'dsp 0, dsp 1' to pd. I did the same test again with 1000
> instances and time doubled.
>
> > > Why is resizing tables so much slower, when tilde-objects are
> > > referencing it? I noticed that even resizing very small tables can be a
> > > cause for audio drop-outs. I wonder whether 'live-resizing' should be
> > > avoided altogether.
> >
> > because the table-accessing objects will only check whether a table
> > exists and of what size it is) when the DSP graph is re-calculated.
> > this is a speed optimization, so those objects don't need to check the
> > table existance/size in each signal block.
> > the way how it is implemented is, that a table is marked as "being used
> > in DSP processing" by a referencing object. as soon as such a table
> > 

Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-09-22 Thread Jonathan Wilkes via Pd-list
Does [soundfiler] rebuild the dsp graph on read, or only if the -resize flagis 
used?  If its the latter then you can just set the right array size ahead of 
time.Then if you still get dropouts you'll know it's the blocking i/o doing it.
-Jonathan
 


 On Tuesday, September 22, 2015 10:50 PM, Matt Barber  
wrote:
   

 There's nothing wrong per se with resizing an array -- but there are good 
reasons not to do it while a patch is running after a [tab*] object has 
referred to it. I have myself only noticed audio dropouts when I'm resizing a 
table with soundfiler; I thought it must have been a disk-access bottleneck 
(soundfiler runs synchronously, yes?), but it would make sense if it in very 
large patches that a resize triggering a DSP recalc could do it. Though, then 
wouldn't adding any tilde object do the same?
On Tue, Sep 22, 2015 at 4:00 PM, Jonathan Wilkes via Pd-list 
 wrote:

In C, what's the overhead of having function_call(return array->x_size) 
insteadof array->x_size inside a perform routine?
If that's not significant, it seems like it'd be better to over-allocate the 
array at creation/resize time and report the requested size to the user.  That 
way reallocation (and dsp-rebuilding) is only necessary if there's a 
substantial size change, or if the array is used by an external that uses the 
old API.
That's certainly more difficult to do than just rebuilding the graph on every 
resizing.  But to me it's preferable to telling new users, "Here's howto resize 
an array, which is a central feature for using objects like [tabplay~] and'Put' 
menu arrays and [soundfiler], but in reality don't use it because[[explanation 
of Pd's implementation details go here]]."
-Jonathan   

  On Tuesday, September 22, 2015 12:05 PM, Roman Haefeli  
wrote:
   

 On Sun, 2015-09-20 at 22:19 +0200, IOhannes m zmölnig wrote:
> On 09/17/2015 11:55 PM, Roman Haefeli wrote:
> 
> > Is the time it takes to recalculate the graph only dependent on the
> > number of tilde-objects running in the current instance of Pd? If so, is
> > that a linear correlation? 10 times more tilde-objects means it takes 10
> > times as long to recalculate the graph?
> 
> [skipping those]

Simple tests suggests that the relation is linear. But maybe this
depends on the kind of graph? What I tested: I created 500 audio
processing abstractions dynamically and then I measured the time it
takes to send 'dsp 0, dsp 1' to pd. I did the same test again with 1000
instances and time doubled.

> > Why is resizing tables so much slower, when tilde-objects are
> > referencing it? I noticed that even resizing very small tables can be a
> > cause for audio drop-outs. I wonder whether 'live-resizing' should be
> > avoided altogether.
> 
> because the table-accessing objects will only check whether a table
> exists and of what size it is) when the DSP graph is re-calculated.
> this is a speed optimization, so those objects don't need to check the
> table existance/size in each signal block.
> the way how it is implemented is, that a table is marked as "being used
> in DSP processing" by a referencing object. as soon as such a table
> changes it's size (or is deleted), the DSP graph is notified - by means
> of recalculation.

Now, after knowing all these facts, it seems unwise to do table resizing
at all, especially for quite small tables. With today's amounts of RAM
available, it seems wise to allocate enough at patch-loading time and
only utilize the necessary part of it.  

> i guess the API could be changed to *unuse* a table (a simple refcounter
> should do), so that as soon as no DSP-object is referencing the object
> within the DSP-graph, any substantial change to it wouldn't trigger a
> DSP  graph recompilation.

The ability to recompile only a partition of the graph in general would
be a huge gain, IMHO. The ability to resize arrays without recompilation
isn't that big an advantage, is it? It would allow for a little simpler
patching, though.

Roman
___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list


   
___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list





  ___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list


Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-09-22 Thread Matt Barber
There's nothing wrong per se with resizing an array -- but there are good
reasons not to do it while a patch is running after a [tab*] object has
referred to it. I have myself only noticed audio dropouts when I'm resizing
a table with soundfiler; I thought it must have been a disk-access
bottleneck (soundfiler runs synchronously, yes?), but it would make sense
if it in very large patches that a resize triggering a DSP recalc could do
it. Though, then wouldn't adding any tilde object do the same?

On Tue, Sep 22, 2015 at 4:00 PM, Jonathan Wilkes via Pd-list <
pd-list@lists.iem.at> wrote:

> In C, what's the overhead of having function_call(return array->x_size)
> instead
> of array->x_size inside a perform routine?
>
> If that's not significant, it seems like it'd be better to over-allocate
> the array at creation/resize time and report the requested size to the
> user.  That way reallocation (and dsp-rebuilding) is only necessary if
> there's a substantial size change, or if the array is used by an external
> that uses the old API.
>
> That's certainly more difficult to do than just rebuilding the graph on
> every resizing.  But to me it's preferable to telling new users, "Here's how
> to resize an array, which is a central feature for using objects like
> [tabplay~] and
> 'Put' menu arrays and [soundfiler], but in reality don't use it because
> [[explanation of Pd's implementation details go here]]."
>
> -Jonathan
>
>
> On Tuesday, September 22, 2015 12:05 PM, Roman Haefeli 
> wrote:
>
>
> On Sun, 2015-09-20 at 22:19 +0200, IOhannes m zmölnig wrote:
> > On 09/17/2015 11:55 PM, Roman Haefeli wrote:
> >
> > > Is the time it takes to recalculate the graph only dependent on the
> > > number of tilde-objects running in the current instance of Pd? If so,
> is
> > > that a linear correlation? 10 times more tilde-objects means it takes
> 10
> > > times as long to recalculate the graph?
> >
> > [skipping those]
>
> Simple tests suggests that the relation is linear. But maybe this
> depends on the kind of graph? What I tested: I created 500 audio
> processing abstractions dynamically and then I measured the time it
> takes to send 'dsp 0, dsp 1' to pd. I did the same test again with 1000
> instances and time doubled.
>
> > > Why is resizing tables so much slower, when tilde-objects are
> > > referencing it? I noticed that even resizing very small tables can be a
> > > cause for audio drop-outs. I wonder whether 'live-resizing' should be
> > > avoided altogether.
> >
> > because the table-accessing objects will only check whether a table
> > exists and of what size it is) when the DSP graph is re-calculated.
> > this is a speed optimization, so those objects don't need to check the
> > table existance/size in each signal block.
> > the way how it is implemented is, that a table is marked as "being used
> > in DSP processing" by a referencing object. as soon as such a table
> > changes it's size (or is deleted), the DSP graph is notified - by means
> > of recalculation.
>
> Now, after knowing all these facts, it seems unwise to do table resizing
> at all, especially for quite small tables. With today's amounts of RAM
> available, it seems wise to allocate enough at patch-loading time and
> only utilize the necessary part of it.
>
> > i guess the API could be changed to *unuse* a table (a simple refcounter
> > should do), so that as soon as no DSP-object is referencing the object
> > within the DSP-graph, any substantial change to it wouldn't trigger a
> > DSP  graph recompilation.
>
> The ability to recompile only a partition of the graph in general would
> be a huge gain, IMHO. The ability to resize arrays without recompilation
> isn't that big an advantage, is it? It would allow for a little simpler
> patching, though.
>
>
> Roman
>
> ___
> Pd-list@lists.iem.at mailing list
> UNSUBSCRIBE and account-management ->
> http://lists.puredata.info/listinfo/pd-list
>
>
>
> ___
> Pd-list@lists.iem.at mailing list
> UNSUBSCRIBE and account-management ->
> http://lists.puredata.info/listinfo/pd-list
>
>
___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list


Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-09-22 Thread Jonathan Wilkes via Pd-list
In C, what's the overhead of having function_call(return array->x_size) 
insteadof array->x_size inside a perform routine?
If that's not significant, it seems like it'd be better to over-allocate the 
array at creation/resize time and report the requested size to the user.  That 
way reallocation (and dsp-rebuilding) is only necessary if there's a 
substantial size change, or if the array is used by an external that uses the 
old API.
That's certainly more difficult to do than just rebuilding the graph on every 
resizing.  But to me it's preferable to telling new users, "Here's howto resize 
an array, which is a central feature for using objects like [tabplay~] and'Put' 
menu arrays and [soundfiler], but in reality don't use it because[[explanation 
of Pd's implementation details go here]]."
-Jonathan   

  On Tuesday, September 22, 2015 12:05 PM, Roman Haefeli  
wrote:
   

 On Sun, 2015-09-20 at 22:19 +0200, IOhannes m zmölnig wrote:
> On 09/17/2015 11:55 PM, Roman Haefeli wrote:
> 
> > Is the time it takes to recalculate the graph only dependent on the
> > number of tilde-objects running in the current instance of Pd? If so, is
> > that a linear correlation? 10 times more tilde-objects means it takes 10
> > times as long to recalculate the graph?
> 
> [skipping those]

Simple tests suggests that the relation is linear. But maybe this
depends on the kind of graph? What I tested: I created 500 audio
processing abstractions dynamically and then I measured the time it
takes to send 'dsp 0, dsp 1' to pd. I did the same test again with 1000
instances and time doubled.

> > Why is resizing tables so much slower, when tilde-objects are
> > referencing it? I noticed that even resizing very small tables can be a
> > cause for audio drop-outs. I wonder whether 'live-resizing' should be
> > avoided altogether.
> 
> because the table-accessing objects will only check whether a table
> exists and of what size it is) when the DSP graph is re-calculated.
> this is a speed optimization, so those objects don't need to check the
> table existance/size in each signal block.
> the way how it is implemented is, that a table is marked as "being used
> in DSP processing" by a referencing object. as soon as such a table
> changes it's size (or is deleted), the DSP graph is notified - by means
> of recalculation.

Now, after knowing all these facts, it seems unwise to do table resizing
at all, especially for quite small tables. With today's amounts of RAM
available, it seems wise to allocate enough at patch-loading time and
only utilize the necessary part of it.  

> i guess the API could be changed to *unuse* a table (a simple refcounter
> should do), so that as soon as no DSP-object is referencing the object
> within the DSP-graph, any substantial change to it wouldn't trigger a
> DSP  graph recompilation.

The ability to recompile only a partition of the graph in general would
be a huge gain, IMHO. The ability to resize arrays without recompilation
isn't that big an advantage, is it? It would allow for a little simpler
patching, though.

Roman
___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list


  ___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list


Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-09-22 Thread Roman Haefeli
On Sun, 2015-09-20 at 22:19 +0200, IOhannes m zmölnig wrote:
> On 09/17/2015 11:55 PM, Roman Haefeli wrote:
> 
> > Is the time it takes to recalculate the graph only dependent on the
> > number of tilde-objects running in the current instance of Pd? If so, is
> > that a linear correlation? 10 times more tilde-objects means it takes 10
> > times as long to recalculate the graph?
> 
> [skipping those]

Simple tests suggests that the relation is linear. But maybe this
depends on the kind of graph? What I tested: I created 500 audio
processing abstractions dynamically and then I measured the time it
takes to send 'dsp 0, dsp 1' to pd. I did the same test again with 1000
instances and time doubled.

> > Why is resizing tables so much slower, when tilde-objects are
> > referencing it? I noticed that even resizing very small tables can be a
> > cause for audio drop-outs. I wonder whether 'live-resizing' should be
> > avoided altogether.
> 
> because the table-accessing objects will only check whether a table
> exists and of what size it is) when the DSP graph is re-calculated.
> this is a speed optimization, so those objects don't need to check the
> table existance/size in each signal block.
> the way how it is implemented is, that a table is marked as "being used
> in DSP processing" by a referencing object. as soon as such a table
> changes it's size (or is deleted), the DSP graph is notified - by means
> of recalculation.

Now, after knowing all these facts, it seems unwise to do table resizing
at all, especially for quite small tables. With today's amounts of RAM
available, it seems wise to allocate enough at patch-loading time and
only utilize the necessary part of it.  

> i guess the API could be changed to *unuse* a table (a simple refcounter
> should do), so that as soon as no DSP-object is referencing the object
> within the DSP-graph, any substantial change to it wouldn't trigger a
> DSP  graph recompilation.

The ability to recompile only a partition of the graph in general would
be a huge gain, IMHO. The ability to resize arrays without recompilation
isn't that big an advantage, is it? It would allow for a little simpler
patching, though.

Roman


signature.asc
Description: This is a digitally signed message part
___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list


Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-09-20 Thread IOhannes m zmölnig
On 09/17/2015 11:55 PM, Roman Haefeli wrote:
> 
> One thing I'd like to know: Is there one graph for all patches in a
> certain instance of Pd? 

yes

> It seems that adding a tilde-object to a patch
> causes the DSP graph to be recalculated.

yes

> Now, if _everything_ is in the
> same graph, this would mean the whole graph needs to be recalculated
> when adding objects (or abstractions containing tilde-objects, for that
> matter), no matter where I put them.

yes

> It would make no difference whether
> I have one big patch with 1000 tilde-objects loaded or 100 smaller
> patches with 10 tilde-objects each, when adding new objects, would it?

no (you're right)

> Is the time it takes to recalculate the graph only dependent on the
> number of tilde-objects running in the current instance of Pd? If so, is
> that a linear correlation? 10 times more tilde-objects means it takes 10
> times as long to recalculate the graph?

[skipping those]

> Or is it even exponential? There
> is no way to partition the graph and update only one partition, is
> there?

no

> 
[...]
> 
> Why is resizing tables so much slower, when tilde-objects are
> referencing it? I noticed that even resizing very small tables can be a
> cause for audio drop-outs. I wonder whether 'live-resizing' should be
> avoided altogether.

because the table-accessing objects will only check whether a table
exists and of what size it is) when the DSP graph is re-calculated.
this is a speed optimization, so those objects don't need to check the
table existance/size in each signal block.
the way how it is implemented is, that a table is marked as "being used
in DSP processing" by a referencing object. as soon as such a table
changes it's size (or is deleted), the DSP graph is notified - by means
of recalculation.

i guess the API could be changed to *unuse* a table (a simple refcounter
should do), so that as soon as no DSP-object is referencing the object
within the DSP-graph, any substantial change to it wouldn't trigger a
DSP  graph recompilation.

gfmadsr
IOhannes



signature.asc
Description: OpenPGP digital signature
___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list


Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-09-20 Thread Jonathan Wilkes via Pd-list
Thanks, Matt.  It seems like your point #1 is one of the main reasons to use Pd.
As far as best practices-- I think the first thing is to go through and see 
under what conditions thegraph could be selectively rebuilt.  Once there's a 
proof of concept that this can be done while still guaranteeing deterministic 
behavior, the best practices are simply documentation of that feature.
But it's really an all or nothing thing.  The current conservative approach is 
way less workto debug and maintain than trying to be efficient for dynamic 
patching.  If we make it possible toselectively rebuild, it's not worth the 
effort if the user still feels like they can trigger a completerebuild just by 
sneezing.  (Or if they find that the constraints keep them from building 
anythinginteresting.)  Practically speaking, I think that means Pd has to be 
smarter about array resizing,and tracking whether wireless tilde objects 
navigate outside of a canvas/abstraction/toplevel.
Seems hard, but of course I don't know the tricks of the trade in this domain.

-Jonathan
 


 On Sunday, September 20, 2015 3:56 AM, Matt Barber  
wrote:
   

 Things are a lot more encapsulated in SuperCollider, and it can afford to be 
more efficient because 1) the DSP flow doesn't need to be in a strict 
correspondence with what appears in a GUI graph, 2) the user is not responsible 
for the DSP flow unless they want to be and do it on purpose with head/tail 
instantiation or node numbering, and 3) there are only a few ways of passing 
information between ugens: directly as arguments to another ugen, variables, 
and buses. Data in an SC Synth is more protected from the outside than anything 
in Pd is (as abstractions in Pd are still in the global space despite the 
dollarsign locality tricks), and the bus system controls I/O to and from Synths 
much more strictly. Pd doesn't enforce any of that because of its pledge to 
keep things global; this makes it extremely flexible, but at the price of a 
potentially more convoluted DSP graph.
What would be interesting to know is whether there are best practices for 
patching that would help out the ugen graph routine.
On Sun, Sep 20, 2015 at 12:30 AM, Jonathan Wilkes  wrote:

Matt-- I don't believe that bug has been fixed.
Roman-- I haven't looked closely at the relevant code, but it looks like Pd 
recalculates the graph-- a single graph for the runninginstance of Pd-- every 
time you add/remove a tilde object.  (Not sure aboutcontrol objects, but it's 
easy to test.)
The reason I'm comfortable speculating about this is the existence ofwireless 
tilde objects like [throw~] and [catch~] which use globalreceiver names.  When 
you change an object inside a tiny patch with100 other patches open in the same 
Pd instance, how would Pd know thatyou aren't altering a [throw~] which has a 
[catch~] in one of the 100 otherpatches?  Same for [send~]/[receive~], 
[delwrite~]/[delread~]/[vd~],[table]/[tab*~], etc.
Here's the dsp_tick routine in d_ugen.c:

void dsp_tick(void)
{
    if (dsp_chain)
    {
    t_int *ip;
    for (ip = dsp_chain; ip; ) ip = (*(t_perfroutine)(*ip))(ip);
    dsp_phase++;
    }
}

That is-- execute each dsp routine in the global array of dsp routines 
untilthere are no more dsp routines to execute.
But this makes me wonder-- how does Supercollider "do its thing"?  Seems likeit 
has an interface to add/remove parts of its dsp graph, and it can do so in a 
much more efficient manner.
-Jonathan



 On Saturday, September 19, 2015 10:56 PM, Matt Barber 
 wrote:
   

 One more thing to think about is how the DSP graph is handled using dynamic 
patching. For a long time there was a "bug" where the last audio object added 
didn't trigger a recalculation and would be left out of the DSP graph until the 
next edit. Is this still the case? The workaround, if I remember correctly, was 
to add one last dummy object at the end of dynamic patching.
Matt
On Thu, Sep 17, 2015 at 5:55 PM, Roman Haefeli  wrote:

Hi all

First, I'm not even sure if 'DSP graph' is the correct term. Pd's
documentation[1] states that all DSP objects are internally arranged
into a linear order which I believe is often called 'DSP graph'. There
are apparently some actions that cause this DSP graph to be rebuilt.
Rebuilding takes time and is often the cause of audio drop-outs. I would
like to have a better understanding of the mechanics going on behind the
scenes with the hope to be able to optimize my Pd programming.

One thing I'd like to know: Is there one graph for all patches in a
certain instance of Pd? It seems that adding a tilde-object to a patch
causes the DSP graph to be recalculated. Now, if _everything_ is in the
same graph, this would mean the whole graph needs to be recalculated
when adding objects (or abstractions containing tilde-objects, for that
matter), no matter where I put them. It would make no difference whether
I have one big patch with 1000 tilde-objects loaded or 100 smaller
patches with

Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-09-20 Thread Matt Barber
Things are a lot more encapsulated in SuperCollider, and it can afford to
be more efficient because 1) the DSP flow doesn't need to be in a strict
correspondence with what appears in a GUI graph, 2) the user is not
responsible for the DSP flow unless they want to be and do it on purpose
with head/tail instantiation or node numbering, and 3) there are only a few
ways of passing information between ugens: directly as arguments to another
ugen, variables, and buses. Data in an SC Synth is more protected from the
outside than anything in Pd is (as abstractions in Pd are still in the
global space despite the dollarsign locality tricks), and the bus system
controls I/O to and from Synths much more strictly. Pd doesn't enforce any
of that because of its pledge to keep things global; this makes it
extremely flexible, but at the price of a potentially more convoluted DSP
graph.

What would be interesting to know is whether there are best practices for
patching that would help out the ugen graph routine.

On Sun, Sep 20, 2015 at 12:30 AM, Jonathan Wilkes 
wrote:

> Matt-- I don't believe that bug has been fixed.
>
> Roman-- I haven't looked closely at the relevant code, but it looks like
> Pd recalculates the graph-- a single graph for the running
> instance of Pd-- every time you add/remove a tilde object.  (Not sure about
> control objects, but it's easy to test.)
>
> The reason I'm comfortable speculating about this is the existence of
> wireless tilde objects like [throw~] and [catch~] which use global
> receiver names.  When you change an object inside a tiny patch with
> 100 other patches open in the same Pd instance, how would Pd know that
> you aren't altering a [throw~] which has a [catch~] in one of the 100 other
> patches?  Same for [send~]/[receive~], [delwrite~]/[delread~]/[vd~],
> [table]/[tab*~], etc.
>
> Here's the dsp_tick routine in d_ugen.c:
>
> void dsp_tick(void)
> {
> if (dsp_chain)
> {
> t_int *ip;
> for (ip = dsp_chain; ip; ) ip = (*(t_perfroutine)(*ip))(ip);
> dsp_phase++;
> }
> }
>
> That is-- execute each dsp routine in the global array of dsp routines
> until
> there are no more dsp routines to execute.
>
> But this makes me wonder-- how does Supercollider "do its thing"?  Seems
> like
> it has an interface to add/remove parts of its dsp graph, and it can do so
> in a
> much more efficient manner.
>
> -Jonathan
>
>
>
> On Saturday, September 19, 2015 10:56 PM, Matt Barber 
> wrote:
>
>
> One more thing to think about is how the DSP graph is handled using
> dynamic patching. For a long time there was a "bug" where the last audio
> object added didn't trigger a recalculation and would be left out of the
> DSP graph until the next edit. Is this still the case? The workaround, if I
> remember correctly, was to add one last dummy object at the end of dynamic
> patching.
>
> Matt
>
> On Thu, Sep 17, 2015 at 5:55 PM, Roman Haefeli  wrote:
>
> Hi all
>
> First, I'm not even sure if 'DSP graph' is the correct term. Pd's
> documentation[1] states that all DSP objects are internally arranged
> into a linear order which I believe is often called 'DSP graph'. There
> are apparently some actions that cause this DSP graph to be rebuilt.
> Rebuilding takes time and is often the cause of audio drop-outs. I would
> like to have a better understanding of the mechanics going on behind the
> scenes with the hope to be able to optimize my Pd programming.
>
> One thing I'd like to know: Is there one graph for all patches in a
> certain instance of Pd? It seems that adding a tilde-object to a patch
> causes the DSP graph to be recalculated. Now, if _everything_ is in the
> same graph, this would mean the whole graph needs to be recalculated
> when adding objects (or abstractions containing tilde-objects, for that
> matter), no matter where I put them. It would make no difference whether
> I have one big patch with 1000 tilde-objects loaded or 100 smaller
> patches with 10 tilde-objects each, when adding new objects, would it?
> Is the time it takes to recalculate the graph only dependent on the
> number of tilde-objects running in the current instance of Pd? If so, is
> that a linear correlation? 10 times more tilde-objects means it takes 10
> times as long to recalculate the graph? Or is it even exponential? There
> is no way to partition the graph and update only one partition, is
> there?
>
> On a related note, I made the following observation and I'm wondering
> if/how that is related to the DSP graph: I create a minimalist patch
> with a small [table foo 100] and I measure the time it takes to 'resize'
> it to 99 with [realtime]. On my box, this takes 0.01 ms. I expected it
> to be fast, since memory access is very quick. Now, I additionally load
> a much more complex patch with many tilde-objects. I 'resize' the table
> again and it still takes only 0.01ms. Now I put a [tabread~ foo]
> somewhere in the patch. Now,'resize'-ing the table foo to 100 takes
> 20ms. Even if I 

Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-09-19 Thread Jonathan Wilkes via Pd-list
Matt-- I don't believe that bug has been fixed.
Roman-- I haven't looked closely at the relevant code, but it looks like Pd 
recalculates the graph-- a single graph for the runninginstance of Pd-- every 
time you add/remove a tilde object.  (Not sure aboutcontrol objects, but it's 
easy to test.)
The reason I'm comfortable speculating about this is the existence ofwireless 
tilde objects like [throw~] and [catch~] which use globalreceiver names.  When 
you change an object inside a tiny patch with100 other patches open in the same 
Pd instance, how would Pd know thatyou aren't altering a [throw~] which has a 
[catch~] in one of the 100 otherpatches?  Same for [send~]/[receive~], 
[delwrite~]/[delread~]/[vd~],[table]/[tab*~], etc.
Here's the dsp_tick routine in d_ugen.c:

void dsp_tick(void)
{
    if (dsp_chain)
    {
    t_int *ip;
    for (ip = dsp_chain; ip; ) ip = (*(t_perfroutine)(*ip))(ip);
    dsp_phase++;
    }
}

That is-- execute each dsp routine in the global array of dsp routines 
untilthere are no more dsp routines to execute.
But this makes me wonder-- how does Supercollider "do its thing"?  Seems likeit 
has an interface to add/remove parts of its dsp graph, and it can do so in a 
much more efficient manner.
-Jonathan



 On Saturday, September 19, 2015 10:56 PM, Matt Barber 
 wrote:
   

 One more thing to think about is how the DSP graph is handled using dynamic 
patching. For a long time there was a "bug" where the last audio object added 
didn't trigger a recalculation and would be left out of the DSP graph until the 
next edit. Is this still the case? The workaround, if I remember correctly, was 
to add one last dummy object at the end of dynamic patching.
Matt
On Thu, Sep 17, 2015 at 5:55 PM, Roman Haefeli  wrote:

Hi all

First, I'm not even sure if 'DSP graph' is the correct term. Pd's
documentation[1] states that all DSP objects are internally arranged
into a linear order which I believe is often called 'DSP graph'. There
are apparently some actions that cause this DSP graph to be rebuilt.
Rebuilding takes time and is often the cause of audio drop-outs. I would
like to have a better understanding of the mechanics going on behind the
scenes with the hope to be able to optimize my Pd programming.

One thing I'd like to know: Is there one graph for all patches in a
certain instance of Pd? It seems that adding a tilde-object to a patch
causes the DSP graph to be recalculated. Now, if _everything_ is in the
same graph, this would mean the whole graph needs to be recalculated
when adding objects (or abstractions containing tilde-objects, for that
matter), no matter where I put them. It would make no difference whether
I have one big patch with 1000 tilde-objects loaded or 100 smaller
patches with 10 tilde-objects each, when adding new objects, would it?
Is the time it takes to recalculate the graph only dependent on the
number of tilde-objects running in the current instance of Pd? If so, is
that a linear correlation? 10 times more tilde-objects means it takes 10
times as long to recalculate the graph? Or is it even exponential? There
is no way to partition the graph and update only one partition, is
there?

On a related note, I made the following observation and I'm wondering
if/how that is related to the DSP graph: I create a minimalist patch
with a small [table foo 100] and I measure the time it takes to 'resize'
it to 99 with [realtime]. On my box, this takes 0.01 ms. I expected it
to be fast, since memory access is very quick. Now, I additionally load
a much more complex patch with many tilde-objects. I 'resize' the table
again and it still takes only 0.01ms. Now I put a [tabread~ foo]
somewhere in the patch. Now,'resize'-ing the table foo to 100 takes
20ms. Even if I remove the [tabread~ foo] again, resizing the table
still takes at least 20ms. There is no way to make it fast again except
restarting Pd. I also figured out that when only a non-tilde [tabread
foo] is refencing the table I'm resizing, the resizing keeps being fast.
Only when tilde-objects are referencing the table, resizing that very
table becomes slow. The actual time seems dependent on the complexity of
the loaded patch(es). And it also corresponds with the time it takes to
send 'dsp 1' to pd (when dsp is switched off).

Why is resizing tables so much slower, when tilde-objects are
referencing it? I noticed that even resizing very small tables can be a
cause for audio drop-outs. I wonder whether 'live-resizing' should be
avoided altogether.

Yeah, that's a bunch of questions... Even when knowing the answer to
only some them, it might clear things up quite a bit.

Roman



[1] "Pd sorts all the tilde objects into a linear order for
running." ( http://msp.ucsd.edu/Pd_documentation/x2.htm#s4.2 )

___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list




___

Re: [PD] Understanding the mechanics of rebuilding Pd's DSP graph

2015-09-19 Thread Matt Barber
One more thing to think about is how the DSP graph is handled using dynamic
patching. For a long time there was a "bug" where the last audio object
added didn't trigger a recalculation and would be left out of the DSP graph
until the next edit. Is this still the case? The workaround, if I remember
correctly, was to add one last dummy object at the end of dynamic patching.

Matt

On Thu, Sep 17, 2015 at 5:55 PM, Roman Haefeli  wrote:

> Hi all
>
> First, I'm not even sure if 'DSP graph' is the correct term. Pd's
> documentation[1] states that all DSP objects are internally arranged
> into a linear order which I believe is often called 'DSP graph'. There
> are apparently some actions that cause this DSP graph to be rebuilt.
> Rebuilding takes time and is often the cause of audio drop-outs. I would
> like to have a better understanding of the mechanics going on behind the
> scenes with the hope to be able to optimize my Pd programming.
>
> One thing I'd like to know: Is there one graph for all patches in a
> certain instance of Pd? It seems that adding a tilde-object to a patch
> causes the DSP graph to be recalculated. Now, if _everything_ is in the
> same graph, this would mean the whole graph needs to be recalculated
> when adding objects (or abstractions containing tilde-objects, for that
> matter), no matter where I put them. It would make no difference whether
> I have one big patch with 1000 tilde-objects loaded or 100 smaller
> patches with 10 tilde-objects each, when adding new objects, would it?
> Is the time it takes to recalculate the graph only dependent on the
> number of tilde-objects running in the current instance of Pd? If so, is
> that a linear correlation? 10 times more tilde-objects means it takes 10
> times as long to recalculate the graph? Or is it even exponential? There
> is no way to partition the graph and update only one partition, is
> there?
>
> On a related note, I made the following observation and I'm wondering
> if/how that is related to the DSP graph: I create a minimalist patch
> with a small [table foo 100] and I measure the time it takes to 'resize'
> it to 99 with [realtime]. On my box, this takes 0.01 ms. I expected it
> to be fast, since memory access is very quick. Now, I additionally load
> a much more complex patch with many tilde-objects. I 'resize' the table
> again and it still takes only 0.01ms. Now I put a [tabread~ foo]
> somewhere in the patch. Now,'resize'-ing the table foo to 100 takes
> 20ms. Even if I remove the [tabread~ foo] again, resizing the table
> still takes at least 20ms. There is no way to make it fast again except
> restarting Pd. I also figured out that when only a non-tilde [tabread
> foo] is refencing the table I'm resizing, the resizing keeps being fast.
> Only when tilde-objects are referencing the table, resizing that very
> table becomes slow. The actual time seems dependent on the complexity of
> the loaded patch(es). And it also corresponds with the time it takes to
> send 'dsp 1' to pd (when dsp is switched off).
>
> Why is resizing tables so much slower, when tilde-objects are
> referencing it? I noticed that even resizing very small tables can be a
> cause for audio drop-outs. I wonder whether 'live-resizing' should be
> avoided altogether.
>
> Yeah, that's a bunch of questions... Even when knowing the answer to
> only some them, it might clear things up quite a bit.
>
> Roman
>
>
>
> [1] "Pd sorts all the tilde objects into a linear order for
> running." ( http://msp.ucsd.edu/Pd_documentation/x2.htm#s4.2 )
>
> ___
> Pd-list@lists.iem.at mailing list
> UNSUBSCRIBE and account-management ->
> http://lists.puredata.info/listinfo/pd-list
>
>
___
Pd-list@lists.iem.at mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list