Discuss Scratch
- Discussion Forums
- » Bugs and Glitches
- » Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
- RDoc
-
46 posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
If I broadcast a message inside a block defined with the “Run Without Screen Refresh” flag set it takes about .5 sec. The same block with the flag cleared takes about .03 sec. with Turbo Mode off. With Turbo Mode on, the one with the flag cleared is instantaneous, the other takes the same .5 sec.
What's happening and is there a fix?
You can see it in this project: BlockTest
What's happening and is there a fix?
You can see it in this project: BlockTest
Last edited by RDoc (Aug. 2, 2014 17:28:25)
- drmcw
-
1000+ posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
Yes the run without screen refresh only speeds up the block not external scripts, so if you do a broadcast and wait in a run without screen refresh block then you'll get enormous amounts of lag as the block is being forced to wait but scratch is only trying to run that block. if the run without screen refresh block is itself taking a long time then the block is ony interrupted every .5 seconds so broadcasts will only be run after .5 seconds which seems to be what you are seeing.
- RDoc
-
46 posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
I've changed the project to separate the broadcast and wait times.
We may be saying the same thing, but I'd state it that a wait operation is only checked on some kind of interrupt. If the block has the “Run Without Screen Refresh” flag cleared, it's being interrupted every screen refresh (1/60 sec?). However, if the flag is set, the wait isn't checked until the .5 sec interrupt (keep alive?) comes around.
That behavior IMHO is VERY obscure and close to being buggy. In all cases, flag set or cleared, I think it would be far better if waits were handled with their own events, or at least checked on a fast clock.
We may be saying the same thing, but I'd state it that a wait operation is only checked on some kind of interrupt. If the block has the “Run Without Screen Refresh” flag cleared, it's being interrupted every screen refresh (1/60 sec?). However, if the flag is set, the wait isn't checked until the .5 sec interrupt (keep alive?) comes around.
That behavior IMHO is VERY obscure and close to being buggy. In all cases, flag set or cleared, I think it would be far better if waits were handled with their own events, or at least checked on a fast clock.
- drmcw
-
1000+ posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
Scratch runs at 30 fps, so
would take 1 second in a custom block with run without screen refresh cleared. You should try and keep custom blocks using run without screen refresh as localised and fast as possible. Relying on the 0.5 second pre-emption is bad practice and means you're trying to do too much in a block. Sounds like you have a forever loop in there. Can you share the script? The other problem with the 0.5 second pre-emption is that if it happens then it means the next time the custom block is called it will be called as if run without screen refresh is disabled
- RDoc
-
46 posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
There's a link to the project in the OP. There's pretty much nothing in the block except for the wait.
I don't think that the .5 sec interrupt changes the block behavior since I'm not seeing it in my test script. It always takes about the same time.
I don't think that the .5 sec interrupt changes the block behavior since I'm not seeing it in my test script. It always takes about the same time.
Last edited by RDoc (Aug. 3, 2014 16:10:33)
- drmcw
-
1000+ posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
Well yes you've got broadcast and wait and wait until blocks, so are just asking for lag! First rule of “run without screen refresh” is don't have any delays in the custom block!
- RDoc
-
46 posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
Well I guess we'll just have to disagree about what constitutes good design in multiprocessing systems.
- drmcw
-
1000+ posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
?? Is this not a question about custom blocks and run without screen refresh? Well I guess we'll just have to disagree about what constitutes good design in multiprocessing systems.
- RDoc
-
46 posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
I really appreciate your explaining what is happening here, but I think that this behavior is a bug or design shortcoming in Scratch. Under the hood, Scratch is a multiprocessing system, more accurately, it's a multi-threaded system. To allow pseudo simultaneous operation, each sprite and the stage run in what amounts to separate threads, each of which seems to get a fixed time interval (a screen refresh?) to run, then another sprite's thread gets to run during the next interval, etc. All the sprites that aren't waiting for something are given a turn to run. If a sprite is waiting for something, such as a key or a broadcast message to complete, it isn't runnable, so it doesn't get a time slice.
The block sending the message is in one sprite (or the stage) which runs as a thread and the wait is essentially a yield to allow other threads to run. The sprite receiving the broadcast message is a separate thread that runs to completion at which point the broadcast wait is completed. That means that the broadcasting block's thread is now runnable since the condition its waiting for is complete. In Scratch though there doesn't seem to be a mechanism to restart the thread without waiting for some kind of timer interrupt. If it's running without screen refresh, apparently the .5 sec timer is the only one available.
Normally in these systems, immediately after something that can be waited on, such as a broadcast message or a wait on a key, completes, all threads that were stopped because they were waiting for it are marked as now being runnable. They get put onto the list with all the other runnable threads, and are started when its their turn just like all the rest. In this case, where the broadcast message completes and there aren't any other running threads left, such systems often are designed to immediately start the thread that was waiting since its the only runnable one. There's no need to wait for the start of the next time interval once the thread that was running in the current time interval stops.
I think that's what Scratch should do too. Once a broadcast message completes, the sprite waiting on it should be marked runnable and, if nothing else was running, should be immediately restarted. At a minimum it should be marked as runnable and put into the same list as all the other runnable threads, in this case it would be alone. That would shorten the delay in this case to less than a screen refresh cycle even if threads were only restarted when a new time interval started.
IMHO the problem with the current design of Scratch is that its behavior is really mysterious, especially as it isn't explained anywhere I'm aware of.
The block sending the message is in one sprite (or the stage) which runs as a thread and the wait is essentially a yield to allow other threads to run. The sprite receiving the broadcast message is a separate thread that runs to completion at which point the broadcast wait is completed. That means that the broadcasting block's thread is now runnable since the condition its waiting for is complete. In Scratch though there doesn't seem to be a mechanism to restart the thread without waiting for some kind of timer interrupt. If it's running without screen refresh, apparently the .5 sec timer is the only one available.
Normally in these systems, immediately after something that can be waited on, such as a broadcast message or a wait on a key, completes, all threads that were stopped because they were waiting for it are marked as now being runnable. They get put onto the list with all the other runnable threads, and are started when its their turn just like all the rest. In this case, where the broadcast message completes and there aren't any other running threads left, such systems often are designed to immediately start the thread that was waiting since its the only runnable one. There's no need to wait for the start of the next time interval once the thread that was running in the current time interval stops.
I think that's what Scratch should do too. Once a broadcast message completes, the sprite waiting on it should be marked runnable and, if nothing else was running, should be immediately restarted. At a minimum it should be marked as runnable and put into the same list as all the other runnable threads, in this case it would be alone. That would shorten the delay in this case to less than a screen refresh cycle even if threads were only restarted when a new time interval started.
IMHO the problem with the current design of Scratch is that its behavior is really mysterious, especially as it isn't explained anywhere I'm aware of.
- drmcw
-
1000+ posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
OK let's try and explain it how I understand it:
Scratch is a single threaded program. You can have multiple when green flag clicked script,s for example, and the scripts may appear to run at the same time but will be run in sequence. For multiple sprites the scripts will be run in the sprites z-order so the sprite nearest the front goes first. For same scripts running within the same sprite it's harder to work out which will go first as I think it's the order the scripts were written
Scratch runs at 30 fps and will try and run all the scripts that are scheduled to run within each frame. A script will be run until it either, comes to a natural end or stop block, or runs a wait or and wait block, or completes one iteration of a loop (repeat, forever, repeat until). If after running all the scripts the screen has not been changed in any way then the scripts will be run again. If however the screen was updated in some way then the screen will be drawn and the scripts will wait for the next frame. Turbo mode changes this behaviour and even if the screen was changed will keep the scripts running so they don't wait for the next frame.
In a custom block if you set the run without screen refresh option then the block will be run until it completes and ignore frame updates hence the name, like turbo mode does. BUT it is just for the custom block and remember Scratch is single threaded. So that block will be run as fast as it can ignoring screen updates and loop iterations until it ends. If you put any waits in there then you halt the entire program. Other scripts may be scheduled to run but they won't until the custom block is finished. Having a run without screen refresh block wait for something to happen in another script is disaster! The Scratch designers must've realised that this could be a problem and if a run without screen refresh block takes more than about 0.5 seconds then it is stopped and the next time it is run it runs with run without screen refresh disabled.
Scratch is a single threaded program. You can have multiple when green flag clicked script,s for example, and the scripts may appear to run at the same time but will be run in sequence. For multiple sprites the scripts will be run in the sprites z-order so the sprite nearest the front goes first. For same scripts running within the same sprite it's harder to work out which will go first as I think it's the order the scripts were written
Scratch runs at 30 fps and will try and run all the scripts that are scheduled to run within each frame. A script will be run until it either, comes to a natural end or stop block, or runs a wait or and wait block, or completes one iteration of a loop (repeat, forever, repeat until). If after running all the scripts the screen has not been changed in any way then the scripts will be run again. If however the screen was updated in some way then the screen will be drawn and the scripts will wait for the next frame. Turbo mode changes this behaviour and even if the screen was changed will keep the scripts running so they don't wait for the next frame.
In a custom block if you set the run without screen refresh option then the block will be run until it completes and ignore frame updates hence the name, like turbo mode does. BUT it is just for the custom block and remember Scratch is single threaded. So that block will be run as fast as it can ignoring screen updates and loop iterations until it ends. If you put any waits in there then you halt the entire program. Other scripts may be scheduled to run but they won't until the custom block is finished. Having a run without screen refresh block wait for something to happen in another script is disaster! The Scratch designers must've realised that this could be a problem and if a run without screen refresh block takes more than about 0.5 seconds then it is stopped and the next time it is run it runs with run without screen refresh disabled.
- RDoc
-
46 posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
I mostly agree with your explanation, but that's a description of a cooperative multi-tasking system. Scratch may be single threaded as far as the computer's operating system is concerned, but it is running it's own multi-tasking system internally with each sprite a separate task. My contention is that Scratch's system is either buggy or has a design issue.
In my test case, the wait after the broadcast is satisfied in one screen refresh, at which point no script is running and the screen isn't changing, yet the waiting script, which is now perfectly runnable, is not restarted. It appears that when the broadcast and wait is executed, the broadcast is immediately run, the receiving sprite is allowed to run to completion, and the waiting sprite execution stopped. When the broadcast operation ends however, the waiting sprite isn't restarted if it has Run Without Screen Refresh set even though nothing else is runnable. Incidentally, don't think Run Without Screen Refresh is disabled when it finally runs since my script does a second broadcast and wait and the same thing happens, or perhaps it is but the handling of the second broadcast and wait is buggy.
In any case, I think this behavior makes no sense. If Scratch can stop the sending script and run the receiving script and knows enough to resume the sending script .5 sec later, it should be able to immediately resume the sending script when the receiving script exits. Just because a script doesn't wait at the end of a loop, the way waits are handled for it shouldn't be any different from any other script. Obviously if it's waiting, and there's no way to notice that the wait satisfied, nothing is going to happen. Perhaps what's happening is that only after .5 sec and the script is stopped is it put on the list for the normal runnable checking. I'd think it would be better if it were put on the list to be checked immediately when it entered the wait state.
In my test case, the wait after the broadcast is satisfied in one screen refresh, at which point no script is running and the screen isn't changing, yet the waiting script, which is now perfectly runnable, is not restarted. It appears that when the broadcast and wait is executed, the broadcast is immediately run, the receiving sprite is allowed to run to completion, and the waiting sprite execution stopped. When the broadcast operation ends however, the waiting sprite isn't restarted if it has Run Without Screen Refresh set even though nothing else is runnable. Incidentally, don't think Run Without Screen Refresh is disabled when it finally runs since my script does a second broadcast and wait and the same thing happens, or perhaps it is but the handling of the second broadcast and wait is buggy.
In any case, I think this behavior makes no sense. If Scratch can stop the sending script and run the receiving script and knows enough to resume the sending script .5 sec later, it should be able to immediately resume the sending script when the receiving script exits. Just because a script doesn't wait at the end of a loop, the way waits are handled for it shouldn't be any different from any other script. Obviously if it's waiting, and there's no way to notice that the wait satisfied, nothing is going to happen. Perhaps what's happening is that only after .5 sec and the script is stopped is it put on the list for the normal runnable checking. I'd think it would be better if it were put on the list to be checked immediately when it entered the wait state.
- pete-d
-
5 posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
Sorry to jump in here a couple of months later, but I came across this discussion after running into the exact same problem.
And as a professional programmer with decades of experience, I agree 100% with RDoc. At the very least, it's incredibly counter-intuitive that turning screen refresh off will cause things to slow down.
The argument about the long-running block is a red herring. I realize Scratch is implemented using Flash (why??? when the whole Internet is moving to JavaScript, the upgraded Scratch is tied to an old and non-universal platform), and that changes to some extent what's possible. But there's no reason that having a custom block that has screen refresh turned off should prevent other blocks from executing.
Indeed, every indication in my tests is that broadcasting the message does result in the receiver executing its block. So it's not that the receiver block doesn't execute (which would be the case if turning off screen refresh really did prevent any other block from executing). Instead, it's just that the wait time for the completion of the receiver block goes up drastically.
Maybe this is due to some fundamental architectural issue in the implementation of Scratch, and can't easily be fixed. But it's still 100% a bug. There's just no valid design reason that Scratch should behave this way.
And as a professional programmer with decades of experience, I agree 100% with RDoc. At the very least, it's incredibly counter-intuitive that turning screen refresh off will cause things to slow down.
The argument about the long-running block is a red herring. I realize Scratch is implemented using Flash (why??? when the whole Internet is moving to JavaScript, the upgraded Scratch is tied to an old and non-universal platform), and that changes to some extent what's possible. But there's no reason that having a custom block that has screen refresh turned off should prevent other blocks from executing.
Indeed, every indication in my tests is that broadcasting the message does result in the receiver executing its block. So it's not that the receiver block doesn't execute (which would be the case if turning off screen refresh really did prevent any other block from executing). Instead, it's just that the wait time for the completion of the receiver block goes up drastically.
Maybe this is due to some fundamental architectural issue in the implementation of Scratch, and can't easily be fixed. But it's still 100% a bug. There's just no valid design reason that Scratch should behave this way.
- Lucario621
-
100+ posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
I definitely see what you mean. It's pretty counter-intuitive that broadcasts are slower under turbo speed, and there's no apparently normal reason for it. For now if you want to optimize your projects to work well with turbo-mode, I think you're better off not using broadcasts and just focus on activating different parts of the project using variables and conditionals (with forever loops).
- michaeladamkatz
-
1 post
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
I'm very grateful for this thread. I had a “run without screen refresh” checked for my block, and I was using “broadcast and wait” and it was going very slowly. I thought the problem must be that I had too many sprites and they each had too many handlers, and all the string comparing was bogging Scratch down and my whole design just wasn't going to work. Now I've unchecked “run without screen refresh” and while I'd rather it not have the screen refresh *and* run fast, at least my project is viable when “run without screen refresh” is off, whereas before it wasn't.
I agree that this interaction between “run without screen refresh” and “broadcast and wait” is counter-intuitive. One is just “don't do a draw until this function ends” and the other is “remote procedure call”. It is not intuitive that they would have much to do with each other. At worst I would expect “calling into” the other sprite's message handler to defeat run without screen refresh, but not to cause long delays.
I agree that this interaction between “run without screen refresh” and “broadcast and wait” is counter-intuitive. One is just “don't do a draw until this function ends” and the other is “remote procedure call”. It is not intuitive that they would have much to do with each other. At worst I would expect “calling into” the other sprite's message handler to defeat run without screen refresh, but not to cause long delays.
- Sonickyle
-
1000+ posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
fyi Scratch 2.0 is completly singlethreaded. Everything is ran on a single processor.
- drmcw
-
1000+ posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
No. Broadcasts and broadcast with wait will still work in turbo mode. The point of all this boils down to; I definitely see what you mean. It's pretty counter-intuitive that broadcasts are slower under turbo speed, and there's no apparently normal reason for it. For now if you want to optimize your projects to work well with turbo-mode, I think you're better off not using broadcasts and just focus on activating different parts of the project using variables and conditionals (with forever loops).
Don't use wait blocks in more bocks that are set to run without screen refresh. e.g broadcast and wait.
Perhaps it would be more intuitive if it was called “Turn yield off” instead of run without screen refresh?
- QuanHo2105
-
34 posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
i cannot hide my scripts
somehow it is brodcasting a message when it is not brodcasting
i tried looking in the scripts and i didn't find bugs
then there is no brodcasting of the seme meassage giving me the bug
somehow it is brodcasting a message when it is not brodcasting
i tried looking in the scripts and i didn't find bugs
then there is no brodcasting of the seme meassage giving me the bug
Last edited by QuanHo2105 (April 12, 2022 21:57:26)
- QuanHo2105
-
34 posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
NVM The sprite is touching mouse pointer when it is hiding i cannot hide my scripts
somehow it is brodcasting a message when it is not brodcasting
i tried looking in the scripts and i didn't find bugs
then there is no brodcasting of the seme meassage giving me the bug
the project is an aquarium sim still in production
Last edited by QuanHo2105 (April 12, 2022 22:02:54)
- MathKing08142013
-
51 posts
Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.
NVM The sprite is touching mouse pointer when it is hiding i cannot hide my scripts
somehow it is brodcasting a message when it is not brodcasting
i tried looking in the scripts and i didn't find bugs
then there is no brodcasting of the seme meassage giving me the bug
the project is an aquarium sim still in production
Don’t necropst. Necroposting is when you comment on a forum years after it clearly died. Make your own thread instead.
- Discussion Forums
- » Bugs and Glitches
-
» Broadcasting messages in a block with "Run Without Screen Refresh" on is VERY slow.