Metro doesn't start according to right-left ordering...

aengus's icon

Hi,

I have a question regarding the right-left ordering of operations when turning on a metro object.

In the attached patcher, the output of a toggle is connected to a metro and a print. The metro is to the right of the print object and its output is connected to a second print object. When you turn on the toggle, the message from the left hand print object appears in the max window before that from the print object attached to the metro.

Given the right-left execution order, I would have thought that the message due to the first bang from the metro object would appear first. Why is this not the case?

Thanks,

Aengus.

1064.metro_right_left.maxpat
Max Patch
Ben Bracken's icon

Hi Aengus,

It is because the metro is banging at an interval of 250 ms. So the metro does indeed receive the bang before the [print control] object, but it does not send a bang to the [print metro] object until 250 ms has elapsed.

-Ben

aengus's icon

Hi Ben,

No I don't think that's it. According to the docs, the metro object sends out its first bang as soon as you tell it to start (try it with a metro interval of 5000 ms or so- it's really obvious that the first bang is emitted much sooner than 5 s).

Perhaps it's that the metro starting procedure is deferred to a low priority thread...?

Aengus.

Ben Bracken's icon

whoops, yes, you are totally correct. I had forgotten that metro always sends a bang out when turned on.

I recall that if there is no quantization, metro's first bang is scheduled with a delay of 0 and outputs in the timer thread.

-b

Noob4Life's icon

way i understand it, the answer to your original question: it's because it goes through first, and then into so the order of messaging from would be: to then to and separately from into (as soon as is messaged to act) because execution order is always right-to-left/top-to-bottom.

_____________________________________
Never fear, Noob4Life was never here!

aengus's icon

Hmmm... but is the execution order not that it goes to the (top) rightmost object connected first and then through to the end of that execution chain (i.e. through to ) before going to the next object to the left?

Also, it makes no difference if you drag the down so it is below .

Noob4Life's icon

"but is the execution order not that it goes to the (top) rightmost object connected first and then through to the end of that execution chain (i.e. through to ) before going to the next object to the left?"

no, the message comes from toggle, and only goes to and , it doesn't go straight to . so you're first comparing the execution order between and , then after that, it's all dependent on the objects below/next in the chain.

"Also, it makes no difference if you drag the down so it is below . "

sorry, top-to-bottom is less a graphic/visual reference and more one regarding the ordered chain of messages or the way objects are connected(you could say messaging comes in from the top inlet(s) of the object, processed, and then output is sent through the bottom outlet(s) to the next object in the chain...), in the toggle-metro-printcontrol-printmetro case, you consider the messaging from to and first, then you consider the messaging from to next.

Max Patch
Copy patch and select New From Clipboard in Max.

try this patch, copy everything including "----------begin_max5_patcher----------"
and
"-----------end_max5_patcher-----------"
and then in Max, from 'File' menu, choose "New From Clipboard":

_____________________________________
Never fear, Noob4Life was never here!

aengus's icon

Ok, I see what you're saying, but I don't see how it's consistent with the attached patcher. There's no metro involved, but the right hand is at the end of a line of objects, whereas the left hand is directly connected to the toggle, and yet happens first.

Am I missing something?

1065.right-left_2.maxpat
Max Patch
Noob4Life's icon

ya, this is why i was careful how i worded it when i said, "then after that, it's all dependent on the objects below/next in the chain."

calls the scheduler clock(with delay 0 first and then delay again every millisecond duration you specify by argument), while math objects don't depend on scheduler(they call no clock function internally) so they are free to do their thing.
(i'm not sure about how the scheduler prioritizes, but calling a clock function is probably more intensive than simply doing math on a message internally)

______________________________________
Never fear, Noob4life was never here!

aengus's icon

It certainly appears that you're right- the metro and math objects behave differently- but it doesn't really answer my original question. I know that this is the case- I just don't understand _why_ it was designed that way!

Noob4Life's icon

haha, i have no idea why anyone designs anything any way but usually everything has to do with some crucial decision someone had to make early on and then this gets battered into legacy.

thankfully, you can free yourself of right-to-left ordering with smart use of the object so i never really worry about that particular original choice of design(it did have to be either left-to-right or right-to-left, though, because someone had to decide on some order which people could rely on graphically).

______________________________________
Never fear, Noob4life was never here!

Ben Bracken's icon

metro is built to work in the timing thread, along with other things that depend on receiving things in order in this thread. If you want the other print object to also be in the timer thread, throw a delay 0 between it and the toggle.

The cool thing about metro is that if you do want to use quantization, the first bang will actually fire based on whatever quantization you have set. This thread exists specifically to make sure that there aren't a bunch of other things, like, say, math operations, interrupting the order of time sensitive activities. Handy stuff if certain things need to actually happen in order.

-Ben

aengus's icon

Noob4Life- unfortunately the trigger object doesn't help in this situation!

Ben, that's very interesting to know. I guess that's my question answered...

Noob4Life's icon

(and if i recall correctly, the timer thread is a high-priority thread)

Max Patch
Copy patch and select New From Clipboard in Max.

[EDIT: what situation are you trying to get? the patches you've posted could easily be manipulated by trigger object:

]

______________________________________
Never fear, Noob4life was never here!

Noob4Life's icon
Max Patch
Copy patch and select New From Clipboard in Max.

and if you wanted to print before WITHOUT repeat bangs in the beginning, you could also do this among many other things:

______________________________________
Never fear, Noob4life was never here!

aengus's icon

Ah, yes, sorry, that would work. I thought you were suggesting something like the attached patcher.

1066.trigger_no_use_here.maxpat
Max Patch
Roman Thilenius's icon

thats strange. i really did not know this, because usually you have a
metro somewhere completly at he beginning of something.

bens explanation that the between the 2 different queues there is
no order sounds logical, but somehow it feels strange to see how the
"faster" metro message is overrounded by the left one.

AlexHarker's icon

I'm going to go out on a limb and say Ben's explanation is not quite the whole picture.

If you swap up to a higher priority thread then the order of execution can seem out of order (higher thread event happens after events that look like they should wait). The *scheduling* of an event with delay 0 happens at the right time in the order, and then the low priority thread moves on - I'd guess the scheduler then services the scheduled action next time it executes. A similar thing happens when you switch down to a lower priority (defer / deferlow), but it is desired in that scenario.

The important thing to know is that *EVERY* time you schedule an event (no matter what thread from) you seem to place that event later in terms of order of execution. This means that you need to schedule in any parallel message routes at the same time to maintain order of execution. If you do it in series it doesn't work. The patch below should clarify.

Max Patch
Copy patch and select New From Clipboard in Max.

This is one of the more esoteric timing things that happens in max....
Often these things don't matter in a particular context, so they can easily go unnoticed.
I became aware of it when I started experiencing threading issues and designed an object to move any message up to the high priority thread. In that case I made the object so it would execute immediately if triggered from the high priority thread. The standard objects don't seem to work this way, and I doubt they ever will (beacuse it may well break old patches)

seejayjames's icon

right-to-left overrides top-to-bottom, unless the objects are exactly vertically aligned. Then the top-to-bottom comes into play.

Lots going on beneath the hood with scheduler timings etc., sometimes you can make [trigger] do the magic, but other times (depending on what's down the chain from it) it won't do what you anticipate (the other outlets start to fire before the first chain has completed, like writing to a file). With delays and defers it can become even more of a spaghetti timing mess...or it can be sublime!

BUT, with general experimentation and making sure your time-critical elements are given high priority, you shouldn't have many problems in this regard. [trigger] is incredibly useful to keep things straight, for most operations. can't believe I used Max for several years before learning about it. Now it comes up all the time in my patches, and it's been so handy...

aengus's icon

Alex, thanks for posting those observations and patch. Very useful. I wonder if this stuff is nicely documented anywhere. I agree it doesn't arise very often, but it would be nice to have a reference for when it does.

Emmanuel Jourdan's icon

A simple rule... when you have event schedule the order is not guaranteed anymore, if you need some synchronization you'll have to use one metro instead of two for instance (and a counter or something).

Roman Thilenius's icon

[buddy] might come handy.

but one can also just turn the ovberdrive off me thinks. which makes metro pointless.

-110

AlexHarker's icon

The situation is the same with overdrive on or off.....

Emmanuel Jourdan's icon

@Alex

could you elaborate what you mean?

AlexHarker's icon

@emmanuel.

Sure no problem. Here on my MBP 17" 3.0GHz Core 2 Duo the above patch I posted behaves the same whether overdrive is on or off.

Also - I *believe* that if my assumptions are correct :

Assumptions - The order in which events are scheduled when delay == 0 will be maintained (I'm assuming that the scheduling mechanism is threadsafe, and only one thread can be calling it at a time, and it adds things to some kind of call stack / list that is serviced in order.

That if you schedule in parallel with delay == 0 from a single thread that the events will be scheduled in the same order as order of execution implies. I can't be sure of this without knowing the contents of the source code, but I can't easily imagin why it work another way. Your post seems to imply some unpredictablitiy in *this* situation.

Max Patch
Copy patch and select New From Clipboard in Max.

To clarify, I believe order of execution in the below patch is deterministic and the same under all conditions. I'd be happy to know if that is not the case - an explanation why would as be great if applicable / possible:

Joshua Kit Clayton's icon

Alex, in your last patch, there should be no chance of ordering reversal. the reason it was a problem in the first patch of this thread is because metro outputs in the scheduler thread which is processed at some future time, and the other chain is still happening in the same execution call as the mouse down for trigger. In your patch, they are both put on the scheduler for a future time, in sequence, and that order is preserved when the scheduler executes.

Hope this helps.

AlexHarker's icon

Thanks Joshua - that confirms everything is just as I had thought - very useful to know.