BasicMicro - Forums

www.basicmicro.com
It is currently Mon May 21, 2012 12:53 am

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 35 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Mon Feb 28, 2011 6:26 am 
Offline
Citizen
User avatar

Joined: Thu Feb 17, 2011 3:17 pm
Posts: 18
Hi,

I'm working on a robot project using the ARC-32, and have noticed most operations in Basic taking a fair amount of time to execute in comparison to the equiverlant in assembly. The program i'm making is very processor intensive so I'm trying to save as many micro-seconds as possible. Now I don't mind writing in assembly (it's kind of fun having to think about programming at a low level again :) ), but I am curious why there is such a difference between the two languages. Is Basic executed in a different way to inline assembly?

Also, are there any examples of hservo and hserin/hserout in assembly? As I've found entering and leaving asm{} blocks incurs a performance cost (12uS), so if I can do these in assembly I can stay in a single block for longer.

Thanks in advance,
-1


Top
 Profile  
 
 Post subject: Re: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Mon Feb 28, 2011 8:09 am 
Offline
Master

Joined: Tue Nov 21, 2006 9:34 am
Posts: 527
Personally I find for lots of things the basic does a great job here, but I have also found some places where the speed can really hit you. Things like simple interrupt handlers and the like.

As for using assembly language, I have done a fair amount of it. I have written some serin/serout type functions. Note: they only take buffers and counts and do not do any of the fancy things that the basic does (conversion of types and the like). It has been posted in several threads up on Lynxmotion as I used it before as part of the XBee work... Can explain more if you are interested.

Another option you may have is C/C++. There are two sets of libraries that have been developed. One: http://www.lynxmotion.net/viewtopic.php?f=4&t=6136 by MinionBuilder has a lot of nice features, but I think he has mainly supported the Bap40 and Bap28. The second one, is one that I have been playing with: http://www.lynxmotion.net/viewtopic.php?f=45&t=6677. I don't have as many different sensors supported, but I do have support the Arc32. I also have code in place to do the equivlent of HSERVO on the three different platforms....
Note: my code is simply something I am doing for fun, there are probably many places it can be improved on and there are probably many bugs... So if you decide to try it, I will try to help out, but...

Kurt


Top
 Profile  
 
 Post subject: Re: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Mon Feb 28, 2011 9:16 am 
Offline
Site Admin
User avatar

Joined: Thu Mar 01, 2001 11:00 am
Posts: 903
Location: Temecula, CA
The reason there is a difference is because the basic is tokenized. Each basic command, stores it's arguments along with the function call as a token. Each token takes 32 clock cycles to process without doing anything else. Then the function that token uses is executed which can take anywhere from a couple cycles, like high or low commands, to several thousand instruction cycles, like floating point divides. The average command in basic will execute around 100,000 times per second, some quite a bit faster and some quite a bit slower but none will operate faster than about 500,000 times a second, because of the token processing. The advantage of tokens however is the size they take up. Once a function is added to the library using that functions many times only takes a couple bytes per use.

With asm coding you can obviiously run some commands upt to 8 or 10 million times a second. A simple increment for example. But anything thats even a little complex isn't going to have much advantage over Basic since all the functions in basic are hand written asm code as well.

Also, hserial is probably a bad example of using asm instead of basic. The hserial system adds a hand written asm interrupt handler to do the heavy lifting, and the front end(hserin/hserout) are very simple functions that give you access to the hserial buffers and command modifiers.

_________________
Tech Support
Basic Micro - Robotic Technology Evolved


Top
 Profile  
 
 Post subject: Re: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Mon Feb 28, 2011 12:00 pm 
Offline
Citizen
User avatar

Joined: Thu Feb 17, 2011 3:17 pm
Posts: 18
Thanks for the replies,

Acidtech wrote:
The reason there is a difference is because the basic is tokenized. Each basic command, stores it's arguments along with the function call as a token. Each token takes 32 clock cycles to process without doing anything else. Then the function that token uses is executed which can take anywhere from a couple cycles, like high or low commands, to several thousand instruction cycles, like floating point divides. The average command in basic will execute around 100,000 times per second, some quite a bit faster and some quite a bit slower but none will operate faster than about 500,000 times a second, because of the token processing. The advantage of tokens however is the size they take up. Once a function is added to the library using that functions many times only takes a couple bytes per use.

With asm coding you can obviiously run some commands upt to 8 or 10 million times a second. A simple increment for example. But anything thats even a little complex isn't going to have much advantage over Basic since all the functions in basic are hand written asm code as well.

Thanks for clarifying this Acidtech :D , I had a feeling that Basic was being run via an interpreter of sorts but didn't know for sure. That also explains why i'm getting such a big performance increase, as the actual calculations i'm performing are relatively simple (but doing a lot of them) so even 32 cycles per instruction has a massive effect.

KurtEck wrote:
As for using assembly language, I have done a fair amount of it. I have written some serin/serout type functions. Note: they only take buffers and counts and do not do any of the fancy things that the basic does (conversion of types and the like). It has been posted in several threads up on Lynxmotion as I used it before as part of the XBee work... Can explain more if you are interested.

I'd like to take a look at this :). I plan to pass a lot of data down to my ARC-32 a second, so i'm more interested in getting SerialIn working first, but the option of sending data out occationally would be useful. It doesn't matter if I have to receive and send data as bytes as thats what I was planning to process anyway.

At the moment though I'm just hard coding the actions i want it to perform, and outputting results to servos. Is there a version of hservo that can be used in assembly, or is this another one where using basic makes more sence? Also, how long does a typical move servo instantly command take (in cycles)?

Ideally I'd like to have my main execution loop run entirely in assembly (with Basic for initialisation), as this way I have the most control over how fast my program should run. If it turns out though that hservo and hserial are better to do in basic then I will go down that route and optimise in other areas.


Thanks in advance,
-1


Top
 Profile  
 
 Post subject: Re: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Mon Feb 28, 2011 1:34 pm 
Offline
Master

Joined: Tue Nov 21, 2006 9:34 am
Posts: 527
As Nathan(Acidtech) mentioned, if you are using the hardware serial port, I am not sure how much you will gain using assembly language versus Basic. I will assume that you still want to use the interrupt support such that the input and output of characters will happen as part of interrupt system, and as Nathan mentioned, those interrupts are handled by assembly language functions. The only basic code is for the front end that simply copies code into the queue or grabs data out of the queue. It probably would not be hard to write an assembly language version that did those as well, which may slightly decrease the overhead but not sure by how much. By definition there is lots of time wasted in bit bang functions like the ones I have done, as most of the time you are spinning waiting for each bit to be done. Mine was based on using a timer to control the bit outputs as I was/am having problems with characters being corrupted when other interrupts were happening. Also I had problems with standard input from XBEE using RTS, as when you tell the xbee that your buffer is getting full (RTS line), which the serin does at the end of an input with RTS line specified, the xbee may send two additional characters which are lost. So my version checked for that and cached those away... There are several version of it up on the forums including in the thread: http://www.lynxmotion.net/viewtopic.php ... &start=360 first post on that page. In that zip file there is a folder named something like XBee projects and one of the files is something like XBee taserial support.bas. This is where that code is. There is another file xbee taserial defines.bas that has all of the definitions. These files are used in the different projects...

Now for servos. That is a very complicated thing. As for most servos you must give them a pulse every 20ms. More details about servo requirements in the thread: http://www.lynxmotion.net/viewtopic.php?f=31&t=3172

Again in Basic most everything associated with the servos is handled by assembly language interrupt handlers. When you specify a servo move with no time or speed information, it probably simply writes a couple of words out to where the interrupt handler grabs the pulse width for some channel. It may also do some form of lock to make sure the data is consistent... As I mentioned I recently wrote a version of this code in C and it is complicated, especially on the Arc32. Details about that are in the thread I mentioned before and the thread http://www.lynxmotion.net/viewtopic.php?f=31&t=3172. Personally I would not go down this route to convert this part to assembly language, unless maybe if Nathan might help out some to allow you to have an assembly language wrapper to be able to tell hservo the new data and keep the standard assembly language interrupt handlers...

Good Luck
Kurt


Top
 Profile  
 
 Post subject: Re: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Mon Feb 28, 2011 5:06 pm 
Offline
Site Admin
User avatar

Joined: Thu Mar 01, 2001 11:00 am
Posts: 903
Location: Temecula, CA
Email me for info on how to access the hserin/hserout buffers. I will not try to explain how the backend works for either hservo or hserial but the interface for both is fairly simple and I can document how to acces them in asm.

_________________
Tech Support
Basic Micro - Robotic Technology Evolved


Top
 Profile  
 
 Post subject: Re: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Tue Mar 01, 2011 4:51 pm 
Offline
Master

Joined: Tue Nov 21, 2006 9:34 am
Posts: 527
I emailed Nathan and received a reply, which I will put here. Thanks Nathan!!!

For my own use, I may wrap them up differently and make functions out of them, that either document which registers are used for input/output and are modified and in some cases may have them preserve registers...

Simple HSERIN type function:
Code:
;_HS1_ variables are for uart1 or 2 if only one UART is enabled.
;If both uarts are enables _HS1 variables are for uart1 and _HS2 variables are for uart2

;R2L will hold the next serial byte after executing this function if there is data available
_hserin_wait:
  mov.b  @_HS1_HSERINEND:16,r0h  ;6 Get End address
  mov.b  @_HS1_HSERINSTART:16,r0l ;6 Get Start address
  cmp.b  r0h,r0l       ;2 If equal we have no data
  beq  _hserin_nodata:8     ;4
  extu.w r0          ;Extend to word
  mov.b  @(_HS1_HSERINBUF:16,er0),r2l ;Get byte
  inc.b  r0l        ;Inc Start address
  and.b  #0x7F,r0l      ;Incase of overflow force high bit(0-127)
  mov.b  r0l,@_HS1_HSERINSTART:16 ;Save new Start address
_hserin_nodata:


Simple HSerout function
Code:
;puts value in R0L into buffer to send
_hserout_wait:
  mov.b  @_HS1_HSEROUTEND:16,r1l  ;get end index
  mov.b  @_HS1_HSEROUTSTART:16,r1h ;get start index
  mov.b  r1l,r2l       ;save copy of _HSEROUTEND
  inc.b  r1l        ;inc _HSEROUTEND
  and.b  #0x7F,r1l      ;limit _HSEROUTEND range
  cmp.b  r1l,r1h       ;If end==start buffer is full so wait until space is available
  beq  _hserout_wait:8
  _ints_save_disable
  extu.w r2          ;extend to word
  mov.b  r0l,@(_HS1_HSEROUTBUF:16,er2) ;put next byte at End address
  mov.w  #_HS1_SCR3,r3
  bclr  #7,@er3       ;Disable TIE interrupt
  mov.b  r1l,@_HS1_HSEROUTEND:16  ;Save new End address
  bset  #7,@er3       ;Enable TXI interrupt
  _ints_restore


Simple HSERVO command
Code:
;hservo example,er5 is rate,er5 is position, er0 is servo pin number
.ifdef _DEFENABLEHSERVO2
  and.w   #0x1F,r0
  add.w   #_SERVOTBL,r0     ;calc table data address
  mov.b   @er0,r0l       ;get table data
  xor.b   r0h,r0h       ;isolate servo index
.else
  _OUTPUTFUNCMAC        ;Set pin to output
.endif
  shll.w  r0        ;Multiply index by 2
  and.w   #0x3E,r0      ;limit index
.ifdef _DEF20MHZ
  add.w   #30000,r4
  cmp.w   #59999,r4
  bls   _hservo_cont:8
.else
  add.w   #24000,r4
  cmp.w   #47999,r4
  bls   _hservo_cont:8
.endif
  xor.w   r4,r4
_hservo_cont:
  ;if rate = 0 set new POS immediate
  mov.w   r5,@(_HSERVORATE:16,er0)
  bne   _hservo_nomove:8
  mov.w   r4,@(_HSERVOPOS:16,er0)
_hservo_nomove:
  ;if current POS = 0 set new POS immediate
  mov.w   @(_HSERVOPOS:16,er0),e4
  bne   _hservo_nomove2:8
  mov.w   r4,@(_HSERVOPOS:16,er0)
_hservo_nomove2:
  mov.w   r4,@(_HSERVONEWPOS:16,er0)


Simple HServoWait function.
Code:
;Example of HSERVOWAIT, er0 holds servo pin number
.ifdef _DEFENABLEHSERVO2
  and.w   #0x1F,r0
  add.w   #_SERVOTBL,r0     ;calc table data address
  mov.b   @er0,r0l       ;get table data
  xor.b   r0h,r0h       ;isolate servo index
.endif
  shll.w  r0         ;Multiply index by 2
  and.w   #0x3E,r0
  mov.w   @(_HSERVONEWPOS:16,er0),r1 ;Get NEWPOS
_hservowaitlp:
  mov.w   @(_HSERVOPOS:16,er0),r2  ;Get current POS
  cmp.w   r1,r2
  bne   _hservowaitlp:8


From these code extracts we should also create several of the other functions as well, such as HSERVOPOS and HSERVOIDLE.

Thanks again!

Kurt


Top
 Profile  
 
 Post subject: Re: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Wed Mar 02, 2011 11:34 am 
Offline
Citizen
User avatar

Joined: Thu Feb 17, 2011 3:17 pm
Posts: 18
Acidtech wrote:
Email me for info on how to access the hserin/hserout buffers. I will not try to explain how the backend works for either hservo or hserial but the interface for both is fairly simple and I can document how to acces them in asm.

Thanks Nathan, I've not been able to get to a computer for a couple of days so sorry for not emailing you, looks like Kurt beat me to it.
This should really help me get this project up and running at the speed i'm looking for.

Quote:
mov.b @(_HS1_HSERINBUF:16,er0),r2l ;Get byte

I've never encountered this syntax, is this the method for accessing elements in a variable array as opposed to getting values from a lookup?

Cheers :D,
-1


Top
 Profile  
 
 Post subject: Re: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Wed Mar 02, 2011 11:47 am 
Offline
Master

Joined: Tue Nov 21, 2006 9:34 am
Posts: 527
Zodius wrote:
...looks like Kurt beat me to it.
This should really help me get this project up and running at the speed i'm looking for.

Quote:
mov.b @(_HS1_HSERINBUF:16,er0),r2l ;Get byte

I've never encountered this syntax, is this the method for accessing elements in a variable array as opposed to getting values from a lookup?


I already knew the hserin/hserout stuff from before, but it is good to get his...

As you probably already know: Appendix A of the H83687 manual is your friend. P439 has the mov instructions. What this move instruction says: take the byte from the address in ER0 plus the 16 bit offset _HS1_HSERINBUF and put it into the register r2l.

Or more or less the same as:
add.w #_HS1_HSERINBUF:16, r0
mov.b @er0, r2l

Yep - should be fun...


Top
 Profile  
 
 Post subject: Re: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Wed Mar 02, 2011 5:04 pm 
Offline
Site Admin
User avatar

Joined: Thu Mar 01, 2001 11:00 am
Posts: 903
Location: Temecula, CA
What Kurt said. :)

Basically its a convienient way to use the same index for multiple arrays/tables without modifying the index variable to point to the specified offsets. Think of this format of the mov instruction as a temporary add to the @er0.

_________________
Tech Support
Basic Micro - Robotic Technology Evolved


Top
 Profile  
 
 Post subject: Re: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Thu Mar 03, 2011 12:59 pm 
Offline
Citizen
User avatar

Joined: Thu Feb 17, 2011 3:17 pm
Posts: 18
Thanks :D That makes a lot of sence.

On an unrelated (and rather embarrasing note), what type and capacitance is this capacitor?

Attachment:
ARC-Cap.png
ARC-Cap.png [ 336.05 KiB | Viewed 1077 times ]


In my haste to test these assembly routines out, I inadventantly connected my battery pack in reverse :cry:. This capacitor was lost in the process (with a bang, smoke and hot glow). Nothing else seems damaged, and from what I've read the LM2940 voltage regulator has reverse battery protection, so I'd like to try and fix it first before splashing out another £130 to get an ARC-32 over to the UK.

Hope you can help.
-1


Top
 Profile  
 
 Post subject: Re: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Thu Mar 03, 2011 1:25 pm 
Offline
Master

Joined: Tue Nov 21, 2006 9:34 am
Posts: 527
My guess is it is something like: http://search.digikey.com/scripts/DkSea ... -5262-1-ND


Top
 Profile  
 
 Post subject: Re: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Thu Mar 03, 2011 2:29 pm 
Offline
Citizen
User avatar

Joined: Thu Feb 17, 2011 3:17 pm
Posts: 18
Is the capacitor actually 100uF then? Mine is a charred black mess so I can't read what capacitance it said (And I can only just make out the 16v on that image). In hindsight i should have taken pictures of the board when I got it :(.

-1


Top
 Profile  
 
 Post subject: Re: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Thu Mar 03, 2011 2:51 pm 
Offline
Master

Joined: Tue Nov 21, 2006 9:34 am
Posts: 527
It has a 107 Marked on it which I believe is a 100uf. the Lynxmotion board has one marked 226 (which I know is 22uf). Third digit is multiplier...

Kurt


Top
 Profile  
 
 Post subject: Re: ARC-32 Performance Difference BASIC vs ASM
PostPosted: Thu Mar 03, 2011 3:37 pm 
Offline
Citizen
User avatar

Joined: Thu Feb 17, 2011 3:17 pm
Posts: 18
Looking at the companies product sheet it seems you're right.

I think I've found some possible replacements. Not surface mountable or tantalum material, but for 21p it's worth a go. Hopefully the rest of my board is intact, as the LM2940 voltage regulator can cope with reverse voltages of -15V or more, whereas a typical electrolytic capacitor blows out at -1V.

Thanks for the help Nathan and Kurt :D. Fingers crossed that I can be back up and running at the weekend.

-1


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 35 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group

phpBB SEO