time goes backwards (and I don't like that)
I can make time go backwards. Here's the file: ========================= Event _e; time _t; spork ~ beatProcess(); while (true) { now + 1.00001::second => _t; _e => now; <<< "returned from _e => now at", now >>>; } fun void beatProcess() { while (true) { _t => now; <<< "broadcasting at", now >>>; _e.broadcast(); me.yield(); } } ========================= And here's the output: ========================= bash-3.2$ chuck foo.ck broadcasting at 44100.441000 returned from _e => now at 44100.000000 broadcasting at 88200.441000 returned from _e => now at 88200.000000 broadcasting at 132300.441000 returned from _e => now at 132300.000000 ========================= The "while(true)" shred sets _t to the time at which it wants to be woken up. Note that (intentionally) the increment is slightly over a second. It then blocks on event _e. Meanwhile, the beatProcess() shred blocks until the time in _t, then triggers event _e to resume execution of the while(true) shred. What happens: - the beatProcess shred triggers _e at time 44100.441000 - the while() shred returns from its wait at time 44100.0000 One might think that the while(true) shred woke up *before* _e got triggered, but Apple isn't yet building computers with tachyon technology. Can someone tell me what's really going on??? Failing that, know any doctors who will prescribe a selective serotonin reuptake inhibitor to keep me from tearing my hair out? Thanks. - Rob
Rob;
One might think that the while(true) shred woke up *before* _e got triggered, but Apple isn't yet building computers with tachyon technology.
I fear the exact same happens on the battered old AMD build here and running Linux. I'm really quit sure I didn't put anything expensive, rare or exotic in here.
Can someone tell me what's really going on??? Failing that, know any doctors who will prescribe a selective serotonin reuptake inhibitor to keep me from tearing my hair out?
This is quite clearly wrong, the two times should be the same. Something has gone wrong in the Shreduler; I've been suspecting there have been changes to the shreduler since the last version as some of the execution order in my sequencer has gone very odd indeed, needing a extra ms of advanced time just to get the shreds to execute in the right order but the cause of this has eluded me. I'm going to test this with some older versions of ChucK, in the meantime; I'll past my edits to your code below, I edited it slightly, removing one un-nesicary yield and adding a extra printed line to have ChucK compare the times instead of me, the point to that is to get rid of rounding errors caused by printed values being truncated after six digits after the decimal point and because I'm lazy. This, to put it bluntly, looks very bad and very wrong; seroteine uptake inhibitors take way too long to get going, let's form a hunting party. Get the nets, the pitch-forks and war drums and let's catch this bug! ;¬) Yours, Kas. ==============pasted code below============== Event _e; time _t; time foo; spork ~ beatProcess(); while (true) { now + 1.001::second => _t; _e => now; if (foo > now) <<<"bang">>>; now => foo; <<< "returned from _e => now at", now >>>; } fun void beatProcess() { while (true) { _t => now; if (foo > now) <<<"bang">>>; now => foo; <<< "broadcasting at", now >>>; _e.broadcast(); } }
Kas:
This is quite clearly wrong, the two times should be the same.
*Whew* -- thanks -- I was worried that I was suffering a dissociative fugue (not to be confused with a counter-fugue). A hint to the hunting party: the "wrong" time returned by now always seems to be an integer. It's as if the fractional part is getting lopped off - either by truncation or rounding, I'm not sure which. Fetch me my halberd! - Rob On 13 Mar 2009, at 15:49, Kassen wrote:
Rob;
One might think that the while(true) shred woke up *before* _e got triggered, but Apple isn't yet building computers with tachyon technology.
I fear the exact same happens on the battered old AMD build here and running Linux. I'm really quit sure I didn't put anything expensive, rare or exotic in here.
Can someone tell me what's really going on??? Failing that, know any doctors who will prescribe a selective serotonin reuptake inhibitor to keep me from tearing my hair out?
This is quite clearly wrong, the two times should be the same. Something has gone wrong in the Shreduler; I've been suspecting there have been changes to the shreduler since the last version as some of the execution order in my sequencer has gone very odd indeed, needing a extra ms of advanced time just to get the shreds to execute in the right order but the cause of this has eluded me. I'm going to test this with some older versions of ChucK, in the meantime; I'll past my edits to your code below, I edited it slightly, removing one un-nesicary yield and adding a extra printed line to have ChucK compare the times instead of me, the point to that is to get rid of rounding errors caused by printed values being truncated after six digits after the decimal point and because I'm lazy.
This, to put it bluntly, looks very bad and very wrong; seroteine uptake inhibitors take way too long to get going, let's form a hunting party. Get the nets, the pitch-forks and war drums and let's catch this bug! ;¬)
Yours, Kas.
==============pasted code below==============
Event _e; time _t; time foo;
spork ~ beatProcess();
while (true) { now + 1.001::second => _t; _e => now; if (foo > now) <<<"bang">>>; now => foo;
<<< "returned from _e => now at", now >>>; }
fun void beatProcess() { while (true) { _t => now; if (foo > now) <<<"bang">>>; now => foo; <<< "broadcasting at", now >>>; _e.broadcast(); } }
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
Rob; *Whew* -- thanks -- I was worried that I was suffering a dissociative fugue
(not to be confused with a counter-fugue).
Just because ChucK has bugs doesn't mean you're not insane, these two factors might be independent :¬p.
A hint to the hunting party: the "wrong" time returned by now always seems to be an integer. It's as if the fractional part is getting lopped off - either by truncation or rounding, I'm not sure which.
There is definitely some rounding error going on. Here is a edit of the code that lops off some zeros. This version never prints "bang" in 1.2.1.2. ================= Event _e; time _t; time foo; spork ~ beatProcess(); while (true) { now + 1.01::second => _t; _e => now; if (foo > now) <<<"bang">>>; now => foo; <<< "returned from _e => now at", now >>>; } fun void beatProcess() { while (true) { _t => now; if (foo > now) <<<"bang">>>; now => foo; <<< "broadcasting at", now >>>; _e.broadcast(); //me.yield(); samp => now; } } ==========================
Fetch me my halberd!
I think it's hiding in rounding in the Shreduler, let's set fire to the shreduler and see if it comes out! In all seriousness; this sounds tricky, I reported a hard to pinpoint execution order error to Ge before and said I suspected something had changed in the shreduler since last version. Ge replied he couldn't remember changing anything to it. The odd thing is that the bug I saw would come and go with using different samples (as in .wav files) but clearly samples only come in integer durations if we express them in samp's. Grumble. Oh, well, at least we've got it cornered. Kas.
Uh-oh. I just thought to check what version of ChucK I'm running: ================= [poorbook15-8:~] r% chuck --version chuck version: 1.2.1.2 (dracula) exe target: mac os x : universal binary http://chuck.cs.princeton.edu/ ================= ...that is, I AM seeing scheduling errors in 1.2.1.2. And you say that you DON'T see the scheduling errors in 1.2.1.2. Curiouser and curiouser. Let me know how I can help. - Rob On 13 Mar 2009, at 16:21, Kassen wrote:
Rob;
*Whew* -- thanks -- I was worried that I was suffering a dissociative fugue (not to be confused with a counter-fugue).
Just because ChucK has bugs doesn't mean you're not insane, these two factors might be independent :¬p.
A hint to the hunting party: the "wrong" time returned by now always seems to be an integer. It's as if the fractional part is getting lopped off - either by truncation or rounding, I'm not sure which.
There is definitely some rounding error going on. Here is a edit of the code that lops off some zeros. This version never prints "bang" in 1.2.1.2.
================= Event _e; time _t; time foo;
spork ~ beatProcess();
while (true) { now + 1.01::second => _t; _e => now; if (foo > now) <<<"bang">>>; now => foo;
<<< "returned from _e => now at", now >>>; }
fun void beatProcess() { while (true) { _t => now; if (foo > now) <<<"bang">>>; now => foo; <<< "broadcasting at", now >>>; _e.broadcast(); //me.yield(); samp => now; } } ==========================
Fetch me my halberd!
I think it's hiding in rounding in the Shreduler, let's set fire to the shreduler and see if it comes out!
In all seriousness; this sounds tricky, I reported a hard to pinpoint execution order error to Ge before and said I suspected something had changed in the shreduler since last version. Ge replied he couldn't remember changing anything to it. The odd thing is that the bug I saw would come and go with using different samples (as in .wav files) but clearly samples only come in integer durations if we express them in samp's.
Grumble. Oh, well, at least we've got it cornered.
Kas. _______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
Rob; ...that is, I AM seeing scheduling errors in 1.2.1.2. And you say that you
DON'T see the scheduling errors in 1.2.1.2. Curiouser and curiouser.
Sorry; either I was unclear or you misunderstood me but I suspect that in this case 1.2.1.2 introduced some issues that weren't previously there; especially the issue that you are reporting here doesn't materialise in that form in 1.2.1.1 for me. I hope that clarifies? Yours, kas.
You are right: I misread your note and overlooked the fact that adding 1.001 *worked* in 1.2.1.2 and adding 1.00001 failed in 1.2.1.2. I got it now. 'Pologies. Dang, everyone else reading this list must be really tired of this thread. Move along, nothing to see here... - Rob On 13 Mar 2009, at 17:18, Kassen wrote:
Rob;
...that is, I AM seeing scheduling errors in 1.2.1.2. And you say that you DON'T see the scheduling errors in 1.2.1.2. Curiouser and curiouser.
Sorry; either I was unclear or you misunderstood me but I suspect that in this case 1.2.1.2 introduced some issues that weren't previously there; especially the issue that you are reporting here doesn't materialise in that form in 1.2.1.1 for me.
I hope that clarifies?
Yours, kas.
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
Rob;
Dang, everyone else reading this list must be really tired of this thread. Move along, nothing to see here...
I really don't think so; IMHO this is a very serious matter that touches upon the very fundaments of ChucK. I feel the Shreduler should behave and do things in order. Of course the Shreduler is a purely abstract device and we can't actually do a thousand things in-between two cycles of a modern CPU but it still should act as advertised and not round. We're talking ChucK here and timing should be completely deterministc and be predictable in a documented way. Much more likely is that it's a friday night. ;¬) Cheers, Kas.
Okay: have built a fresh 1.2.1.2 AND a fresh 1.2.1.1 and observe the same error in both versions. Here's a revised test program that nicely demonstrates that the problem lies with rounding: if the fractional part of now between 0.0 and 0.5 (inclusive), it rounds down. If it is greater than 0.5, it rounds up. And when the time is rounded up, it appears that yield() doesn't yield. ==============pasted code below============== Event e; spork ~ costello(); abbot(); fun void abbot() { while (1) { now + 44100.25::samp => time later; <<< "abbot(1):", now, later >>>; later => now; <<< "abbot(2):", now, later >>>; e.broadcast(); <<< "abbot(3):", now, later >>>; me.yield(); <<< "abbot(4):", now, later >>>; } } fun void costello() { while (1) { <<< "costello(1):", now >>>; e => now; <<< "costello(2):", now >>>; } } ==============pasted output below============== [poorbook15-8:Chuck/chuck-1.2.1.1-dev/src] r% ./chuck --version chuck version: 1.2.1.1b (dracula) exe target: mac os x : powerpc http://chuck.cs.princeton.edu/ [poorbook15-8:Chuck/chuck-1.2.1.1-dev/src] r% ./chuck ~/bar.ck abbot(1): 0.000000 44100.250000 costello(1): 0.000000 abbot(2): 44100.250000 44100.250000 abbot(3): 44100.250000 44100.250000 costello(2): 44100.000000 // 0.25 rounded down costello(1): 44100.000000 abbot(4): 44100.250000 44100.250000 abbot(1): 44100.250000 88200.500000 abbot(2): 88200.500000 88200.500000 abbot(3): 88200.500000 88200.500000 costello(2): 88200.000000 // 0.5 rounded down costello(1): 88200.000000 abbot(4): 88200.500000 88200.500000 abbot(1): 88200.500000 132300.750000 abbot(2): 132300.750000 132300.750000 abbot(3): 132300.750000 132300.750000 abbot(4): 132300.750000 132300.750000 abbot(1): 132300.750000 176401.000000 costello(2): 132301.000000 // 0.75 rounded up, failed to yield costello(1): 132301.000000 abbot(2): 176401.000000 176401.000000 abbot(3): 176401.000000 176401.000000 costello(2): 176401.000000 // 0.0 behaves costello(1): 176401.000000 abbot(4): 176401.000000 176401.000000 abbot(1): 176401.000000 220501.250000 abbot(2): 220501.250000 220501.250000 abbot(3): 220501.250000 220501.250000 costello(2): 220501.000000 costello(1): 220501.000000 abbot(4): 220501.250000 220501.250000 abbot(1): 220501.250000 264601.500000 abbot(2): 264601.500000 264601.500000 abbot(3): 264601.500000 264601.500000 costello(2): 264601.000000 costello(1): 264601.000000 abbot(4): 264601.500000 264601.500000 abbot(1): 264601.500000 308701.750000 C-c C-c[chuck]: cleaning up...
Ok, sorry, we do need to .yield; it just doesn't make a difference in the current version of ChucK. The code below will print lots of "bang" in the current version and will never do so in 1.2.1.1, clearly something in the Shreduler changed. Also; I needed to advance time by a samp, just yielding wouldn't do; that's likely a error as well. Event _e; time _t; time foo; spork ~ beatProcess(); while (true) { now + 1.0001::second => _t; _e => now; if (foo > now) <<<"bang">>>; now => foo; <<< "returned from _e => now at", now >>>; } fun void beatProcess() { while (true) { _t => now; if (foo > now) <<<"bang">>>; now => foo; <<< "broadcasting at", now >>>; _e.broadcast(); samp => now; } ..so far I'm inclined to conclude that there was something changed to the shreduler and that soomethign else was wrong in the shreduler of 1.2.1.1 as well as just yielding should be have been enough. Sigh. Kas.
Kas: I think you're right about two separate bugs (time goes backward, yield doesn't always yield), and I think this code makes it clearer: ==============pasted code below============== Event e; spork ~ costello(); abbot(); fun void abbot() { while (1) { now + 1.00001::second => time later; <<< "abbot(1):", now, later >>>; later => now; <<< "abbot(2):", now, later >>>; e.broadcast(); <<< "abbot(3):", now, later >>>; me.yield(); <<< "abbot(4):", now, later >>>; } } fun void costello() { while (1) { <<< "costello(1):", now >>>; e => now; <<< "costello(2):", now >>>; } } ==============annotated output below============== [poorbook15-8:~] r% chuck bar.ck abbot(1): 0.000000 44100.441000 // abbot about to block on later => now costello(1): 0.000000 // costello gets a chance to run abbot(2): 44100.441000 44100.441000 // abbot unblocks, about to broadcast abbot(3): 44100.441000 44100.441000 // abbot has broadcast, about to yield() costello(2): 44100.000000 // abbot yielded, costello runs BUT NOW IS TRUNCATED costello(1): 44100.000000 // costello is about to block on e => now abbot(4): 44100.441000 44100.441000 // abbot has yielded, about to loop. abbot(1): 44100.441000 88200.882000 // abbot about to block on later => now abbot(2): 88200.882000 88200.882000 // abbot unblocks, about to broadcast abbot(3): 88200.882000 88200.882000 // abbot has broadcast, about to yield abbot(4): 88200.882000 88200.882000 // abbot has yielded BUT COSTELLO DIDN'T RUN abbot(1): 88200.882000 132301.323000 // abbot about to block on later => now costello(2): 88201.000000 // costello runs, BUT NOW IS TRUNCATED costello(1): 88201.000000 // etc... abbot(2): 132301.323000 132301.323000 abbot(3): 132301.323000 132301.323000 // abbot has broadcast, about to yield costello(2): 132301.000000 // aha! the yield worked! costello(1): 132301.000000 abbot(4): 132301.323000 132301.323000 abbot(1): 132301.323000 176401.764000 =========================== Note that yield() seems to take effect sometimes and not others. Ugh. If anyone asks me to, I can write this as a more automated test to check for both errors. Is there an official "test harness" for ChucK, i.e. using asserts() or the equivalent? - Rob
Robert Poor wrote:
If anyone asks me to, I can write this as a more automated test to check for both errors. Is there an official "test harness" for ChucK, i.e. using asserts() or the equivalent?
There is an Assert.ck class at http://github.com/heuermh/lick/tree/master which loosely follows JUnit. See also, e.g. ArrayListTest.ck. michael
participants (3)
-
Kassen
-
Michael Heuer
-
Robert Poor