spin code incredible slow
Chris Micro
Posts: 160
Hello togther,
I tried to make a little waveform generator in spin. But it seems to be incredible slow.
I assume that the loop only can run with a speed of approximately 1KHz. Is that possible?
I tried to make a little waveform generator in spin. But it seems to be incredible slow.
I assume that the loop only can run with a speed of approximately 1KHz. Is that possible?
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OneSecond = 80_000_000 'SysClk: Number of clk cycles in one second FSample = 2_000 ' sampling frequency LeftOutputPin = 10 ' PWM Pin for left analog signal RightOutputPin = 11 ' PWM Pin for right analog signal VAR LONG Phase OBJ DAC : "DualDac" PUB MAIN Dac.Start(LeftOutputPin,RightOutputPin) Triangle(200,5000) PUB Triangle(pitch,duration)|freqInc,temp,temp2 '' duration in ms freqInc:=65536/FSample*pitch temp:=duration*FSample/1000 temp2:=OneSecond/FSample repeat temp phase+=freqInc phase&=$FFFF Dac.Write(phase,phase) waitcnt(temp2+cnt)
Comments
yes, I know, assembler is very fast. But I hoped, that the propeller has so much "horsepower" that even in spin it should be possible to write a waveform generating routine. Is it 80cylces at 80Mhz? Than a spin operation should take 1uSec?
I will try a very "corse" estimation. My cyle loop looks like this:
The estimated caldulation would be in this case 21uS ~= 50KHz. But my measurements with the oszilloskop it seems to have under 2Khz. That would mena, the cycle time is 10 times slower.
Probably the problem is in the Dac.Write Method . It would be good do have a spin code debugger.
Edit: never mind, you posted before I did.
temp2 is 40000, so that waitcnt takes ~500us, not 3.
Post Edited (mpark) : 4/16/2009 6:49:17 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
JMH
sorry, well, yes temp2 depends on the sample frequency
This leads to the 500us delay. The time I estimated for the delay was the fastest possible time.
But fact is, as soon I go up with the the FSample paramter ( let's say to 20KHz) the loop is much slower than the demanded time.
You should add the time2 to cnt before you execute all the code. But then you have to be sure that your code is done before cnt reaches the calculeted value, otherwise you'll wait for ~50sec.
In Dac.write(phase, phase) you use the same parameter twice. So, you sould modify write to only have one parameter. Passing parameters needs time.
Dac.write can propably be run in a extra COG and maybe in PASM. That would speed up things as well.
Thank you for this, I will try it. Dac.write is running in it's own core.
What I'm not shure about, is, if the calling of this method takes much more time than I estimate.
Or is there a better way of passing variables to an object than implementing a dedicated method?
Instead of using variables in the DAC object you can use variables in the code using the object and pass the adress of this variable to the Init. Then your code does not have to call the write function, which simply passes the LeftValue and RightValue to the object internal variables. Instead you can write the values to the variables you know directly. So, one call less with all the parameter passing overhead.
Strange: An FSample value above 15KHz seems to disable the program.
I'm wondering why your small code change speed up the loop that fast.
Than I came to the solution of changing the values by invoking a method of the object which seems in the way of object oriented programming much more elegant.
If you could show me, how to pass the pointers, I would be very glad.
What I do not unterstand: Are the varibles of the object than held in the global or the local memory?
To hight FSample does not disable the program. waitcnt only missed the calculated cnt-value, which means that you have to wait for ~50sec which is the time when cnt wraps around.
It would be very interesting to see how fast I can get the loop running by passing the DAC-values by a pointer. But as I mentioned one post above I wasn't sucessfull with implemting pointers.
I put the Phase in the VAR section, because the Dac itself is started in the MAIN. So you can't use a local variable of Triangle. If you would move the Dac.Start to Triangle you could use a local variable as well. But then you should make sure that the DAC-COG also gets stopped when leaving Triangle.
The dac then should store the adress of the 3rd parameter somewhere.
VAR
· long dacValue_adress
pub Start(left,right,val_adr )
· dacValue_adress:=adr
....
And later on, when the DAC needs the value, it can access it with:
· long[noparse][[/noparse] dacValue_adress ]
·
What does your "DualDac" object look like?· Seems that it is different than the one distributed within "Source-Code-PE-Kit-Labs-Fundamentals.zip"
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
You can use the counters of the COG which runs your Triangle function.
For begiinners like me ( in the sens of knowing the propeller, not other microntrollers ) it is very essential to have easy objects to be able to learn fast.
I developed this little Synthesizer on an Atmega8 in 'C' which was a little bit challenging at that time becaus it was processing power of the Atmega8 and the C-Compiler Optimiziation was sufficient.
I'm wondering now how complicated it would be in spin on a propeller with its huge processing power. For now it seems to me as if spin consumes to much resources related to 'C' on an Atmega8.
@MagIO2
Thanks for the example. I will try to implement it tomorow.
I'm off for now. At this side of the globe it's 9p.m. an my concetration is weekening.
good night,
chris
1. bytecode stays in HUB-RAM and is fetched one instruction after the other to COG RAM.
2. execution then needs several PASM instructions per bytecode
For a lot of things SPIN is fine, but if you need speed PASM should be used.
An alternative would be to use the ImageCraft C compiler. But this still produces PASM code which is slower than self-written PASM code because of the memory model. It's very difficult to writr a C compiler for this kind of architecture the propeller has. That's why they use the LMM (large memory model) which eliminates the 2nd problem of SPIN code, but still has problem number 1 (massive HUB RAM access).
There is also Catalina C, an open source product which was developed by RossH, a forum member. You can learn about that here: http://forums.parallax.com/forums/default.aspx?f=25&m=339139.
There is currently a drive to get more objects written for the Prop in C, and there are several threads that go into some detail about the various benefits and drawbacks of Spin, PASM, and C. Like any tool, you need to decide which one fits the requirements of the task at hand, as well as your ability to wield it (a chain saw is a horrible tool for cutting wood, if you don't know how to start it).
Ned
Added: You might be interested in looking at the available objects in these two categories of the Object Exchange...
(Signal Generation)
http://obex.parallax.com/objects/category/9/
(Speech and Sound)
http://obex.parallax.com/objects/category/10/
Even if they don't do exactly what you want, they make terrific examples to work from.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"They may have computers, and other weapons of mass destruction." - Janet Reno
Post Edited (WNed) : 4/17/2009 3:23:47 AM GMT
uselly I programm in C. But I tried the catalina C-Compiler. After a little hazzle with installing I was able to compile the test_led.c programm. But unforunatelly the LED didn't blink ( my led is at pin16 not pin 1 and I changed the programm). Because I had this problem in the beginning I thought its not usefull to follow this path.
I think it would be possible to surpass this if these C-Compilers would enable a special tecnic to run short C-Slices internal of one Cog not using LMM. I used to programm Attiny13s in C and they have only 2KBytes of programm memory. It ist even possible with these chips to implement some small Synthesizers in C.
James: Uni is short for university , I know Chris so I just was telling him to show up at my lab so I could give him a short pasm course . I hope he realizes it is me !
For now I learned a lot about the structure of spin and its time limitations. For this my little sound generator project is good because it is so time critical.
I added the following method to my spin DAC-Object to get the address of my DualDac object:
Then I changed the sound loop to access the pointer
result: it does not work
Post Edited (Chris Micro) : 4/17/2009 8:38:59 AM GMT
With the propeller architecture you leave track of classical C compilers and of standard C of course. You'd need some intelligence to decide which block of code belongs together and should run in a COG. E.G. you'd need mechanisms to overlay code in one COG. This intelligence is easier to be outsourced to the developer himself ;o)
By using the LMM, they can use existing C compiler methods which simply create plain PASM code. No efford for building an intelligent compiler.
I personally like the SPIN/PASM combination. SPIN is powerfull enough to run managing code and PASM is for the high-speed drivers.
By the way: Do you have some hint for me what's wrong with my pointer access in the DAC-loop?
Chris: Do you mind posting the whole code ?
Chris: A lot has been said and changed since your first post, so I'd also suggest to give us a complete update of the code.
Have fun.