Shop Learn
FlexBasic.....For "COG" — Parallax Forums

FlexBasic.....For "COG"

Anyone figured out how to use this?

I only get compiler complaints. I suspect that there is some kind of initialization that I'm missing.

Comments

  • ersmithersmith Posts: 5,114

    Here's an example:

    function for "cog" addup( a() as integer, n as integer) as integer
      var sum = 0
      for i = 0 to n
        sum += a(i)
      next i
      return sum
    end function
    
    dim shared testarr(4) = { 1, 2, 3, 4, 5 } as integer
    
    print "sum = ", addup(testarr, 4)
    

    There are significant restrictions on functions placed in COG and LUT memory; see the general compiler documentation for details. In particular, the functions should be leaf functions (not call any other functions... in theory they could call other COG or LUT functions, but the compiler doesn't allow that yet).

  • ersmithersmith Posts: 5,114

    Hmmm, I may have spoken too soon about the leaf function restriction... it looks like that was lifted a while ago.

  • MicksterMickster Posts: 1,940

    But I can't just launch something like this, right?

    dim shared as long cogtest
    
    sub for "cog" addup( )
    do
        cogtest = cogtest + 1
    loop
    end sub
    
    addup
    do
        print cogtest
        pausems 200
    loop
    
  • evanhevanh Posts: 12,043

    If I'm reading Eric correctly, it doesn't start a separate task. The for "cog" feature is just a way to specify routine to be compiled for cogexec rather than the default hubexec.

  • @evanh said:
    If I'm reading Eric correctly, it doesn't start a separate task. The for "cog" feature is just a way to specify routine to be compiled for cogexec rather than the default hubexec.

    Correct.
    The code @Mickster posted will jump into Addup() and never return, as Addup() runs in the same cog that has called it. But if you spawn Addup() into its own cog (with its own stack pace, etc) the code will run as intended, with the value of cogtest being printed every 200 mS.

  • ersmithersmith Posts: 5,114

    Right. FOR "COG" means the function is to be placed in COG memory (and FOR "LUT" means it is to be placed in LUT memory) but the function will still run in the same cog as the rest of the program. To start a new cog you need to use the CPU pseudo-function:

    dim shared as long cogtest
    dim as long stack(20)
    
    sub addup()
    do
      cogtest = cogtest + 1
    loop
    end sub
    
    var id = cpu(addup(), @stack(0))  ' run addup() in a new COG with its own stack
    print "cog "; id; " started"
    do
      print cogtest
      pausems 1000
    loop
    
  • MicksterMickster Posts: 1,940

    @ersmith said:
    Right. FOR "COG" means the function is to be placed in COG memory (and FOR "LUT" means it is to be placed in LUT memory) but the function will still run in the same cog as the rest of the program. To start a new cog you need to use the CPU pseudo-function:

    dim shared as long cogtest
    dim as long stack(20)
    
    sub addup()
    do
      cogtest = cogtest + 1
    loop
    end sub
    
    var id = cpu(addup(), @stack(0))  ' run addup() in a new COG with its own stack
    print "cog "; id; " started"
    do
      print cogtest
      pausems 1000
    loop
    

    Oh yeah, I already have a couple of these happening but I misunderstood it to be like running a routine permanently in only cog memory. Like, with the P1; in cog-mode you get the full 20MIPS but only 4 or 5 MIPS using LMM (?)

  • evanhevanh Posts: 12,043
    edited 2021-11-26 14:45

    All correct. But it's the same cog as was being used to execute in LMM, just like one cog that executes hubexec or cogexec. Your main program is using a cog, and a subroutine/function, in hubexec or cogexec, is still running on the same cog unless a new cog is explicitly launched. Prop1 with LMM is same in this respect.

  • MicksterMickster Posts: 1,940

    @evanh :+1: Understood, many thanks :smile:

  • ersmithersmith Posts: 5,114

    @Mickster said:
    Oh yeah, I already have a couple of these happening but I misunderstood it to be like running a routine permanently in only cog memory. Like, with the P1; in cog-mode you get the full 20MIPS but only 4 or 5 MIPS using LMM (?)

    The difference isn't that extreme in P2 mode, plus FlexBasic already caches loops in COG memory (which further reduces the penalty). So generally it's fine to run code in HUB memory. But if you want extra reliable timing, or have a very frequently used function, then FOR "COG" and FOR "LUT" may be useful. And of course you can combine them with CPU -- that is, if you want a subroutine to run permanently in another cog and be in internal memory in that cog, make the subroutine FOR "COG" or FOR "LUT" and then launch it in the new cog with a CPU command.

Sign In or Register to comment.