Why only one uBasic statement per tick? - General Discussion and Assistance - CHDK Forum

Why only one uBasic statement per tick?

  • 15 Replies
  • 6818 Views
*

Offline zeno

  • *****
  • 891
Why only one uBasic statement per tick?
« on: 11 / January / 2009, 07:44:53 »
Advertisements
It appears that Lua offers better performance than uBasic because it doesn't execute just one statement per 10ms tick. Is there any overwhelming reason why uBasic sticks to this limit or was someone just playing safe?

There is a practical reason for my question. It turns out that on some (most? all?) cameras the response to get_usb_power() has greater precision in Lua than in uBasic, and I think this restriction is the reason.
A570, S100, Ixus 127
Author of ASSIST, STICK, WASP, ACID, SDMInst, LICKS, WICKS, MacBoot, UBDB, CFGEdit

*

Offline reyalp

  • ******
  • 13944
Re: Why only one uBasic statement per tick?
« Reply #1 on: 11 / January / 2009, 18:24:07 »
ubasic needs to yield at some point, but once per tick is probably excessive in most cases. There are a number of ways we could be smarter about this, or give the user more control.

1) Just do N statements per tick. Finding a good compromise value might be hard, and will make timing unpredictable. This is essentially what lua does, where N = 1000 vm instructions (not that this is not quite enough under some circumstances, e.g. shooting). Lua VM instructions are probably a lot faster than ubasic statements.
2) As above, but let the script modify N as desired. You could define the performance critical sections of your script, and manage the sleeping yourself.
3) Sleep when execution time exceeds X. The problem is that we can only get a timing resolution of 10ms, and blocking for 10ms each cycle is probably too much in some cases.
4) Measure CPU requirements of canon tasks somehow ;)

If we can find a higher precision counter (or a count of the number of instruction cycles or something like that), #3 would be pretty good.

If you look at what I did to make comments and labels not yield, I'm sure you can see how to implement some of the above.
Don't forget what the H stands for.

*

Offline zeno

  • *****
  • 891
Re: Why only one uBasic statement per tick?
« Reply #2 on: 12 / January / 2009, 12:17:23 »
Thanks reyalp. I should have done a better search (I've since found useful info in the lua implementation thread).

Of course, what would really help is the discovery of a timer with better than 10ms resolution (as was pointed out in the lua thread) but I plan to do some testing to try to get a handle on ubasic statement execution times anyway.

A570, S100, Ixus 127
Author of ASSIST, STICK, WASP, ACID, SDMInst, LICKS, WICKS, MacBoot, UBDB, CFGEdit

*

Offline zeno

  • *****
  • 891
Re: Why only one uBasic statement per tick?
« Reply #3 on: 14 / January / 2009, 12:05:10 »
I've done some simple experiments on the effect of allowing more than one ubasic statement to execute per tick. Following reyalp, I modified the code in the line_statement routine, replacing the line
Code: [Select]
   statement();
with this:
Code: [Select]
      count = 0;
      t1 = get_tick_count();
      while (1) {
         statement();
         count++;
         t2 = get_tick_count();
         if (t2-t1)
             break; // because the clock has 'ticked'
         if (count == speed)
             break; // because we've executed enough statements
      }                     
I added a basic statement to let me change the value of 'speed' within a script. Then I ran something like this:
Code: [Select]
  l = 1000
  set_speed v
  n = 0
  m = 0
  while n < l
     n = n + 1
     a = get_usb_power
     if a > 0 then m = m + 1
  wend
with values of v from 1 to 5. The results were interesting.

When v was 5 the execution time dropped from just over 50 seconds down to 16. With v set to 4, it took just under 18 seconds. With v=3 it was 24 seconds and with v=2 it was 27.

Even with v set to 5, the loop broke because count=speed 90% of the time. With v=1, it broke that way 98% of the time.

It seems clear that, on an A570 at any rate, the current rule of 1 statement per tick is being very conservative. I'd like to propose that something like this be put into the trunk.
« Last Edit: 14 / January / 2009, 13:17:45 by zeno »
A570, S100, Ixus 127
Author of ASSIST, STICK, WASP, ACID, SDMInst, LICKS, WICKS, MacBoot, UBDB, CFGEdit


*

Offline fudgey

  • *****
  • 1705
  • a570is
Re: Why only one uBasic statement per tick?
« Reply #4 on: 14 / January / 2009, 12:30:38 »
Very nice zeno!

And it's good that you made that speed setting command, some old scripts actually rely on those 10 ms delays.

*

Offline dom-a

  • *
  • 14
Re: Why only one uBasic statement per tick?
« Reply #5 on: 14 / January / 2009, 12:44:24 »
That is very nice.

Would this work if it was used in a motion detection script?

*

Offline fudgey

  • *****
  • 1705
  • a570is
Re: Why only one uBasic statement per tick?
« Reply #6 on: 14 / January / 2009, 13:52:12 »
Would this work if it was used in a motion detection script?

Yes, but would not speed up MD reaction time from motion to shutter opening, because in fast MD scripts md_detect_motion command (CHDK C code) presses the shutter directly without executing any other ubasic commands.

*

Offline reyalp

  • ******
  • 13944
Re: Why only one uBasic statement per tick?
« Reply #7 on: 15 / January / 2009, 03:30:58 »
Note that you do have to return immediately after some statements, because the camera actually needs to do stuff. sleep, press, shoot etc. Look at the lua bindings.

If you want to figure out roughly how long ubasic instructions take, just run a loop for thousands of iterations without any sleep and divide. I suspect you'll hundreds of statements is reasonably safe. Note that the impact of stealing CPU from the camera does depend what the camera is doing.

You should also reset the counter when you sleep, so  a loop like
set_speed 10
while blah
do something
do something else
sleep
wend

will always sleep exactly once per iteration, rather than every 10 statements AND once per iteration.

edit:
actually, since sleep() et al have to break out of the loop and return anyway, just resetting the counter before you enter the loop is fine.

set_speed should be called something else, but a good name is eluding me right now.

I've attached my l33t rem benchmark ;)

« Last Edit: 15 / January / 2009, 03:38:37 by reyalp »
Don't forget what the H stands for.


*

Offline zeno

  • *****
  • 891
Re: Why only one uBasic statement per tick?
« Reply #8 on: 15 / January / 2009, 06:39:34 »
Thanks once again reyalp. I've now made sure that the code breaks out of the loop after statements like 'press', 'sleep' and motion detect (all the ones that have a yiedl in luascript.c).

Thanks for the benchmark code too. Though I didn't say so yesterday, I had put quite a bit of instrumentation into my code to count and time things.

Currently the speed setting statement is now called "set_basic_speedup", but I don't think that's quite right either!
A570, S100, Ixus 127
Author of ASSIST, STICK, WASP, ACID, SDMInst, LICKS, WICKS, MacBoot, UBDB, CFGEdit

*

Offline fudgey

  • *****
  • 1705
  • a570is
Re: Why only one uBasic statement per tick?
« Reply #9 on: 15 / January / 2009, 12:27:22 »
Are rem lines still loaded to RAM? How about comments in Lua?

 

Related Topics