Shop OBEX P1 Docs P2 Docs Learn Events
Question about cog speed — Parallax Forums

Question about cog speed

radialrandyradialrandy Posts: 78
edited 2013-06-03 14:21 in Propeller 1
I ran a simple program to check how fast a cog cycles through a program. So I set a cog to repeat a simple upcount. My main cog runs my lcd display and show the count. In 10 seconds I get roughly 270,000 counts. So that cog only seems to be cycling at 27khz. What am I missing hear? If the microcontroller runs at 80mhz whats slowing a single cog down so much? I attached the code below. Theres alot of extra stuff on there. I just removed enough to run this simple test. PUB buttons is the simple count code in its own cog. Thanks
CON              
  _clkmode = xtal1 + pll16x     'Use the PLL to multiple the external clock by 16
  _xinfreq = 5_000_000          'An external clock of 5MHz. is used (80MHz. operation)
  _OUTPUT       = 1             'Sets pin to output in DIRA register
  _INPUT        = 0             'Sets pin to input in DIRA register  
  _HIGH         = 1             'High=ON=1=3.3v DC
  _ON           = 1
  _LOW          = 0             'Low=OFF=0=0v DC
  _OFF          = 0
  _ENABLE       = 1             'Enable (turn on) function/mode
  _DISABLE      = 0             'Disable (turn off) function/mode

   'LM9033A LCD
  _LCD_cs       = 15             'LCD chip select
  _LCD_rst      = 14             'LCD reset
  _LCD_rs       = 24            'LCD register select
  _LCD_sc       = 25            'LCD serial clock
  _LCD_sd       = 26            'LCD serial data
  _LCD_bl       = 0             'LCD backlight, note this is inverted output, when on, BL is off because of PNP transistor.
 
  'screen sizing constants for 128 x 96 display
  _xtiles       = 8                                     'Each time is 16 pixels x 16 pixels
  _ytiles       = 6                                     'Each tile requires 16 longs
  _screenSize   = (_xtiles * _ytiles * 16)              'Size needed for video memory array

  '***************************************
  ' Misc Definitions
  '***************************************
  mode     = 23     'active high
  up       = 22     'active high
  down     = 21     'active high
  enter    = 20     'active high
  increase = 5     'output
  decrease = 4     'output
  on       = 11
  scram    = 18    'active low
  tb       = 19    'active low
  dpin     = 2    'both din and dout of the mcp3208 are connected to this pin on the prop demo board.
  cpin     = 1    'the clock pin of the mcp3208 is connected to this pin on the prop demo board.
  spin     = 3    'the chip select pin of the mcp 3208 is connected to this pin on the prop demo board.

'**************************************
VAR               'Variables to be located here

  long  VIDEOmemory[_screenSize]
  long  LCDmemory[_screenSize],co2psidisplay,co2psi,pinset,pinset1
  long  stack[1500],volt,offset,boostoffset,liveboost,liveboostav,count,co2av
'***************************************
OBJ             

  LCD       : "Brilldea-LM9033A Driver-Ver002.spin"         
  Gr        : "graphics.spin"                              
  eeprom    : "Propeller Eeprom"
  FD        : "FullDuplexSerialPlus.spin"
  stringObj : "ASCII0_STREngine_1.spin"
  sensor    : "MCP3208.spin"
  filter    : "filter_ma.spin"
'***************************************
PUB main | t0

    


   
  cognew(buttons, @stack[100])
 
   
  LCD.start(_LCD_cs, _LCD_rst, _LCD_rs, _LCD_sc, _LCD_sd, _LCD_bl)
  gr.start
  gr.setup(_xtiles, _ytiles, 0, 0, @VIDEOmemory)
  LCD.reset
  LCD.initialize(0, @LCDmemory)
  LCD.contrast(25)
  sensor.start(dpin, cpin, spin, 255)
  offset := sensor.average(6,10)+10
  boostoffset := sensor.average(5,10)+10  



  repeat
    MainScreen

                                           
    

PUB MainScreen |tic
'***************************************
    volt:= (sensor.average(7,10))/10
    gr.clear
    gr.color(3)
    gr.textmode(2,2,5,4)
    gr.width(0)
    'gr.text(63,71,@TXTlogo)
    gr.text(63,70,stringObj.integerToDecimal(count,8)+1)  'used to test
    gr.finish



    gr.finish      
    gr.copy(@LCDmemory)
    gr.finish 
    LCD.screenUpdate(0,@LCDmemory)



PUB Buttons                                                                 
                                                                          
  repeat

'       co2psi:=(sensor.average(6,10))
'       liveboostav:=(sensor.average(5,10)-boostoffset #>0)/36
 '      liveboost:=(boostfilter(liveboostav))
  '     co2av := filter.ma16(co2psi)
        count:=count+1
        If ina[mode]==1
          count:=0
        if ina[enter]==1
          repeat until ina[enter]==0

         
pub boostfilter(x_meas):x_ret
''4-sample moving average filter, implemented with recursion.
''Max filter update rate ~13000 samples/sec for 1 cog @ clkfreq=80

  ptr &= %00001111                         'mask off all but lower four bits
  sum := sum + x_meas - x_buf16[ptr]
  x_buf16[ptr] := x_meas
  x_ret := sum ~> 4                        'divide sum by 16
  ptr++

DAT
'***************************************

TXTlogo       byte      "Boost Leash",0
TXTco2        byte      "Gate",0 
TXTcntrl      byte      "Leash",0
TXTprs        byte      "Boost Gate",0
TXTlaunch     byte      "Launch Psi",0
TXTStages     byte      "Stages?",0
TXTSetup      byte      "Stage Setup",0
TXTStagez     byte      "1 2 3 4 5",0
TXTT          byte      "Time",0
TXTR          byte      "Rate",0
TXTP          byte      "PSI",0
TXTpsi        byte      "psi",0
TXTTEE        byte      "T",0
TXTPEE        byte      "C",0
TXTB          byte      "B",0
TXTset        byte      "Set",0
TXTlive       byte      "Live",0
TXTpoint      byte      ">",0
TXTrpm        byte      "RPM",0
TXTact        byte      "Act",0
TXTvolt       byte      "Volt",0
TXTa          byte      "A",0

TXTscram      byte      "Scramble",0    'scramble
TXTadd        byte      "Add",0         'scramble
TXTforce      byte      "Force",0       'scramble

x_buf4         long      0,0,0,0           '4-place filter input history buffer
x_buf16        long      0,0,0,0,0,0,0,0   '16-place filter input history buffer
               long      0,0,0,0,0,0,0,0   
sum            long      0
ptr            byte      0

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-06-02 19:09
    The method that increments count is written in Spin. Spin is interpreted, not compiled, so it runs quite a bit slower than assembly. Also, you've got other stuff in the same loop that increments count, further slowing things a bit. Your results are in line with what's to be expected from a Spin program, and you can rest assured that the Spin interpreter is running at the full 80 MHz clock speed (i.e. 20 MIPS).

    -Phil
  • Mike GreenMike Green Posts: 23,101
    edited 2013-06-02 20:20
    The speed of the Spin interpreter is a little misleading for discussing the speed of the Propeller. Most real programs use objects from the Propeller Object Exchange or other libraries of objects and many of these objects use a combination of native Propeller instructions (Propeller Assembly or PASM) and Spin code with the heavily time-dependent stuff written in native Propeller instructions and the interfaces to the user's Spin code written in Spin. The native Propeller code runs in its own cog while the Spin interface code runs in the same cog as the user's program interpreted by one copy of the Spin interpreter.

    Examples of this include a 4-port serial communications object, a servo motor driver that can handle up to 32 servo motors simultaneously, a combination of a general purpose I2C driver and SD card SPI driver that can handle double buffering, and a fast 32-bit floating point object that handles IEEE floating point including a wide variety of transcendental functions.
  • radialrandyradialrandy Posts: 78
    edited 2013-06-03 06:38
    Man I hate that. Has no idea that spin slows things down that much.Ive grown to love spin. But its looking like I need to learn assembly. Are there any training material for learning assembly?
  • Heater.Heater. Posts: 21,230
    edited 2013-06-03 06:52
    What are you trying to do and how fast does it have to go?

    That timing loop of yours is doing a lot of work what with using both graphics and an LCD. Could be that writing that in PASm would not be much faster as all the actual time is used in those other objects.

    You really need to benchmark whatever it is you need to do fast. Use CNT to get the start and end times of sections of code and don't put any display code within the thing you are timing.

    Another neat thing you can do with the Prop is toggle a pin as the loop you are timing goes around. Then you can measure that pin frequency with a scope or frequency counter. Or with a bit of code use another COG to measure the frequency it sees on that pin.

    I would want to check if my Spin code is fast enough for the job before wanting to rewrite it in PASM.

    On the other hand PASM is not so bad. It's about one of the easiest assembler language I have come across and as it's integrated into Spin in is very easy to use.
  • Mike GreenMike Green Posts: 23,101
    edited 2013-06-03 07:01
    Yes, start with the stuff in this thread on learning assembly.

    Don't despair about Spin's speed. Remember that, in most programs, 90% of the program's execution time is spent in 10% of the code. Spin is ideal for the other 90% of the code. The important thing is that you can't tell ahead of time which is which. You have to build the program and get it to work first, then measure how much execution time is spent doing what, and then optimize it ... converting just those pieces needed into assembly.

    The exception, in the case of the Propeller, is when you have highly time-dependent code. Still a lot of that can be done in Spin if it doesn't need too much raw speed.
  • radialrandyradialrandy Posts: 78
    edited 2013-06-03 08:00
    Thanks guys.

    I thought the programs for my lcd display was slowing things down so I set it to update the display every second to see if the simple repeat count:=count+1 in the other cog would speed
    up but it ran at the same speed. Main reason for this testing is that I wanted to use a adc to record a sensor at a high rate but with the whole program it slows way down.
  • FireNWaterFireNWater Posts: 93
    edited 2013-06-03 10:18
    Would compiled C be faster?
  • BatangBatang Posts: 234
    edited 2013-06-03 10:49
    You could also use PropBasic that compiles Basic to assembly to get the full speed potential.

    In about 2 weeks a complete development system for PropBasic will be available to download.

    Cheers.
  • Mike GreenMike Green Posts: 23,101
    edited 2013-06-03 10:55
    Compiled C is faster than Spin, but it takes more memory. If you run out of memory and use one of the extended space memory models that stores part of the program in EEPROM or on an SD-card or other external storage, the program slows down again. The best mix is a combination of a small amount of native instructions (assembly language) along with a compact interpretive code like Spin. With compiled C, you get significantly increased speed for small to moderately large programs and no speed advantage for large programs. Note that it's very easy for what look like small programs to get very large very quickly. Features of the language that seem simple (like floating point or printf statements) can bring in huge libraries that drive the program into the "large and not very fast" region of the performance curve very quickly. Sure, it's possible to override some of this stuff with judicious use of compiler options and special libraries, but that takes effort ... it's not automatic ... and it requires a deep understanding of how the compiler and libraries are put together and interact with each other and the user's program.
  • MicksterMickster Posts: 2,694
    edited 2013-06-03 14:21
    I recommend Harprit's book: "Propeller 102: A beginner's guide to learning PASM"

    I have a copy and I believe it covers the sort of things you are looking for.

    Regards,

    Mickster
Sign In or Register to comment.