[PD-dev] outlet_anything() & threads

Hans-Christoph Steiner hans at eds.org
Wed May 17 14:31:27 CEST 2006


On May 17, 2006, at 11:29 AM, IOhannes m zmoelnig wrote:

> Hans-Christoph Steiner wrote:
>> rest.  But I would like to know if the OS generally buffers USB  
>> data.  If the OS doesn't, I'll bet the hardware does somewhere.
>
> i wouldn't bet. the OS _might_ buffer, the hardware _might_ buffer,  
> and pd _might_ block and have audio-dropouts.

Actually, when talking about HID, the OS does buffer HID data on  
Linux and Darwin.  Its part of the API IIRC.

>>> second, what about latency?
>
>> always does the data getting.  That solves that problem.  As for  
>> latency, there would be no difference in latency if a Pd object  
>> was polling a thread or polling a file in /dev/; that object would  
>> still be polling at the same rate.  Adding a thread would just put  
>> extra code between the Pd object and the /dev/ file.
>
> obviously putting things in a thread is extra code.
> however, polling a thread means reading data from a shared memory  
> segment while polling the /dev/-file means a system call which  
> might block.

Well, since there has been zero problems with clicking with [hid]  
AFAIK, I suspect there is something different going on.  With the  
Linux input event system, [hid] just reads up to 64 events from /dev/ 
input/event? per cycle.

Some profiling of this might be handy.  Some docs would be too, but  
I've never found good docs on the Linux input stuff.  I don't recall  
the details of Mac OS X at the moment, give me a couple days.

>> You add a lot of complexity and more running code for no real  
>> gain.  If you change the data in the middle of a poll interval, I  
>> think you'll be asking for trouble.  The problem here is that I  
>> want multiple instances of an object to be able to output data  
>> from the same device.  The data
>
> iThink, this was the problem ck was addressing.
>
>> coming out of each instance should be exactly the same, or the  
>> chance of strange, hard to find bugs will be high.  If a thread  
>> updates the data in between the poll intervals, then different  
>> instances will output different data in each cycle.
>
> i cannot follow you here.
> when querying data from an external device, then this data can  
> change any instance of time. if i want to use the same data twice  
> then i should use the _same data_ twice and not query an external  
> device 2 times and hope that the data has not changed.
> (i mean: use [hid]->[t a a] and not [t b b]=>[hid]->[hid])

Actually, this is how [hid] currently works and it causes problems.   
The aim in Pd is to have everything appear as if it was running at  
the same logical time.  Therefore every instance of [hid 0] should  
output the exact same data.  Otherwise it breaks this paradigm and  
strange behavior will ensue.

> apart from that, i think ck's master/slave concept also took care  
> of data synchronisity.

If all instances output the exact same data from the polling thread,  
then things will work ok. If the thread updates the data directly in  
memory, and each instance just outputs the data in that memory  
location, for example, then whenever the thread updates the data in  
the middle of a time chunk, different instances will output different  
data.  Like I said above, this breaks the Pd paradigm.


>> Polling latency is not an issue except in rare, customized  
>> situations.  The fastest that Windows and Mac OS X can output HID  
>> data is once every 10 ms.  The linux kernel can do once per 1ms if  
>> you customize things, but its generally 10ms also.  These times  
>> probably all apply to generic USB event data too.
>
> there are 2 kinds of latency we have to think of:
> 1. is the latency between an event appearing at the sensors of the  
> external device and the appropriate data output within pd.
> 2. pd is (among other things) used for audio-processing. therefore  
> audio-latency is a big issue. so if you rely on the OS buffering  
> the data (which imho is a not-so-clever thing to do, especially if  
> you support OSs which are proprietary and where you have no chance  
> to know beforehand which way they'll go) and it does not then you  
> might block the entire pd-thread for 10ms (on w32), just waiting on  
> the hid-data.

HID on Win32 is bad news and will never be really usable for good  
instrument design IMHO.  So I don't seriously consider it.  Instead,  
the HID stuff on Windows will be there for people to play with who  
don't care about high-end performance.  HID works decently on Mac OS  
X, but GNU/Linux is far and away the best platform for this.

Plus I barely know anything about Windows programming.  I'd help  
anyone who wants to do to a good HID implementation on Windows,  
because I will never do it.  I'll just get the basics working.

> this basically means goodbye to all uses of pd which require low  
> latencies. (even blocking the system for 1ms is unacceptable; btw  
> we are currently evaluating linux without hid-support since it is  
> known to block the kernel for up to 0.5ms every now and then)

Do you have any documentation of this?  You have to admit, you guys  
have very specific needs.  I don't know much about that stuff.

For instrument design 0.5ms is not significant, as long as there is  
no click.  To put things into perspective, given a speed of sound of  
350 m/s (at roughly 20 C), it takes the sound from an acoustic guitar  
you are playing 1.5ms to get to your ear (0.5 m).  If you are playing  
with an amp that's 3m away, there is a ~9ms delay before you hear the  
sound.

>
>> Plus Pd has a built-in scheduler, and we are writing Pd objects,  
>> so we should use the Pd scheduler, instead of an external one  
>> (i.e. threads).
>
> what makes you think that?
> your OS has a built-in scheduler why not user that?
> i thought we were talking about data-acquisition and not data- 
> processing.

We are talking about scheduling CPU time.  If you want to follow that  
line of reasoning, why bother using Pd at all?  Just put everything  
into threads.

>> The more threads we add to Pd, the more we take CPU time  
>> completely away from the Pd scheduler.  A couple of threads  
>> probably won't matter, but if we start using a lot of threads, it  
>> will matter.
>
> the thing with threads is, that they don't necessarily use CPU.
> if a thread is blocking for 5 seconds, then any other process  
> (including pd!) can use the CPU in this 5seconds without worrying  
> about the thread; if pd is blocking for 5 seconds then everybody  
> will be switching to max/msp or reaktor or even worse.

> so the only solution to use low-latency pd AND "hid" would be to  
> run 2 instances of pd communicating via netsend or similar.
> these 2 instances will run in separate threads (sic!). but these  
> threads will be far heavier than the tiny read-libusb-thread in  
> your object. the communication between the pd instances will add a  
> processing overhead (and latency, btw) too.
> and of course handling several instances of pd can be painful -  
> even though the problem would be solved in pd-space ;-)

I've run [hid] with a poll time of 1.5ms and got no clicks. In the  
realm of instrument design, that is very low latency.  The HID API  
has its own issues, that I can't solve.  But I don't think threads  
will help with HID.  I think that USB-serial will perform very  
similarly.  If you are using bulk transfer mode for USB, that's a  
different story, for that you'd need a much more complicated  
implementation AFAIK.

Try it out.  Seriously, show me a patch where [hid] causes clicks,  
and we can take it from there.

.hc

________________________________________________________________________ 
____

Using ReBirth is like trying to play an 808 with a long stick.
                                               -David Zicarelli





More information about the Pd-dev mailing list