Code Optimization
John Board
Posts: 371
G'day,
I know it's a long shot, but...
I'm trying to quickly write code for a CMUCamv4, for a competition in a few days, I've written some code to query a T packet in Poll mode using "TC", and then the code to recieve it, and chuck it into a few variables, my code is:
My question is, this code was developed hurriedly, and my spin ain't that great, can anyone show me how to optimize this code? My profiler shows that it's currently running at 95ms, I would like it around the 33ms (or less) mark, is this possible? If so, any suggestions how I might achieve this?
I know it's a long shot, but...
I'm trying to quickly write code for a CMUCamv4, for a competition in a few days, I've written some code to query a T packet in Poll mode using "TC", and then the code to recieve it, and chuck it into a few variables, my code is:
PUB updateTrackingData | x, packet sendCommand(string("TC")) 'Asks camera for the T packet repeat packet := Serial.rx 'Gets first byte from camera and puts in variable if packetStartedFlag 'See section below, where packetStarted flag is set to true if packet == 13 'If a new line has been issued, then take the variables in the element array, and then break them out into variables. cmucamMiddleOfMassX := element[0] cmucamMiddleOfMassY := element[1] cmucamBBoxX1 := element[2] cmucamBBoxY1 := element[3] cmucamBBoxX2 := element[4] cmucamBBoxY2 := element[5] cmucamPerPixTracked := element[6] cmucamBBoxPerPixTracked := element[7] elementNumber := 0 repeat x from 0 to 11 element[x] := 0 repeat x from 0 to 2 subelement[x] := 0 packetStartedFlag := false subelementNumber := 0 elementNumber := 0 quit elseif packet == 32 and subelementNumber => 1 'If there is a space, then compile all the collected ints, and combine them and chuck them into the array. element[elementNumber] := Strings.decimalToInteger(@subelement) elementNumber++ subelementNumber := 0 repeat x from 0 to 2 subelement[x] := 0 elseif packet => 48 and packet =< 57 'If the packet is a number (in ASCII), then chuck it in the n'th index of an array subelement[subelementNumber] := packet subelementNumber++ else if packet == 84 'If the char "T" is recieved, then set the packetStarted flag to true packetStartedFlag := true waitForResult 'Wait for the char ":" to be recieved, signifiying the CMU is ready for another command
My question is, this code was developed hurriedly, and my spin ain't that great, can anyone show me how to optimize this code? My profiler shows that it's currently running at 95ms, I would like it around the 33ms (or less) mark, is this possible? If so, any suggestions how I might achieve this?
Comments
Just off the top of my head I see a couple of little things that could be done differently: The first 8 elements could be moved (bytemove) or copied as two longs into your cmucam--- variables in one operation as your cmucam variables will occupy consecutive byte locations if they are declared in that order. You could also use BYTEFILL to erase elements rather than using a repeat loop.
If you really want speed and console interactivity in a turnkey package you should really use my Tachyon Forth (Beau's SAN routine runs about 7 times faster than Spin)
As for forth... I'll make sure to check it out when I don't have to work 16 hours / day as it is to get it working in an enviroment which I'm familiar with :P
Sure, but as the boy who was late for class and out of breath from pushing his bike said to his teacher "I'm late and out of breath because I had to push my bike". Why didn't you ride it says his teacher, "because I was running late and didn't have time to get on it" the boy says
Yes, but you know your next break won't be until after Friday's comp!
1) I don't see packetStartedFlag being set to false - that should probably go before the sendCommand
2) use a higher baudrate
3) don't use strings.decimaltointeger, instead convert to integer yourself by multiply/accumulate where you store the subelement, using a temp, ie
temp := temp*10 + packet - 48
There other possible tweaks, but this should get you going in the right direction.
Bill
G'day, thanks for the response!
The packetStartedFlag is set to false a few lines above the "quit" statement. This resets the flag for the next time that function is called.
Unfortunatly I'm not able to use a higher baud. I was wanting to run it at 115200, but unfortunatly, when I run it at that baud, there is some lossage in the packets. So I'm running it at 57600.
I'll look into that! I was going to write my own dectoint, but for the sake of prototyping development time, I didn't. I'll look into it now though!
Thanks for the advice!
I did some profiling yesterday of the code I had, but none of the sections of the code themselves, only one line was reaching more than 2ms (the sendCommand(String("TC"))), so it had be baffled as to why the code was taking ~99 ms to run.
I always had my hunches that if I took the camera out of poll mode, and had it continually streaming me tracking data perhaps it would operate faster. I tried this, and it worked. It now operates at the sweet spot of 33ms.
So what was causing the problems? What was happening, is I was querying the camera for tracking data, now since it was not in poll mode it took about 95ms to respond. Why? I don't know, it just did. However, when I put it in poll mode, I presume it still takes around 95ms to respond, but after that it's continually streaming the latest tracking data.
Anyway, problem solved! Thanks for all your help!
-John