Shop OBEX P1 Docs P2 Docs Learn Events
copy array — Parallax Forums

copy array

stefstef Posts: 173
edited 2011-11-09 00:06 in Propeller 1
Hi

Just a general question. Can somebody help me to the simplest way to copy array from the on to the other

I have 10 arrays of 20 positions.
ex: long A1[19]
long A2[19]
....
long A10[19]

I want to do the following.
Throw away the content of A1. Put everything from A2 in A1, put everything from A3 in A2 .... , Put everything from A10 in A9 and finally fill A10 with new data.(A bit like shifting the old data out and adding new data at the end.


This is simple explained and I hope you understand the basic idea. I have tried already to approach this but got always stuck. Is their somebody that has an idea behind the approach to this?

I'm working in spin.


Thanks for any sugestion

Stef

Comments

  • Mike GMike G Posts: 2,702
    edited 2011-11-07 05:33
    Use BYTEMOVE (DestAddress, SrcAddress, Count ), page 58 in the Propeller Manual.
    BYTEMOVE(@A1, @A2, 20)
    

    or
    BYTEMOVE(@A1, @A2, 20 * (NUMBER_OF_20_BYTE_ARRAYS - 1))
    
  • stefstef Posts: 173
    edited 2011-11-07 06:17
    Hi Mike

    Thanks. I never used this and overlooked it. I will give it a try.

    I see that you sugest bytemove but my var is type long. It it intentional that you say bytemove? Is it also possible with longmove?
    What happens if I use the one instaid of the other?

    Stef
  • AribaAriba Posts: 2,690
    edited 2011-11-07 06:43
    Because you have long-arrays you shod use longmove instead of bytemove.
    ' copy array
      longmove(@A1[0], @A2[0], 20)
    
    ' move array items down
      longmove(@A1[0], @A1[1], 19)
      A1[19] := newData
    

    Andy
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-11-07 09:57
    The definition

    long A1[19]

    only gives you 19 longs and not 20 positions as stated in the first post. Here you get what you define. It's only the index range which decreases. The range is 0 - 18 in this case.
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-11-07 10:09
    And by the way ... what's the reason for moving the data besides keeping the COG busy?

    You should rather increase a pointer to the start of data:
    long A[200]
    long start, end
    
    start :=0
    end :=180
    
    repeat
      ' fill the end of the buffer
      repeat i from 0 to 19
        A[ end+i ] := getVale() ' whatever you need to do here
    
      ' do something with the whole data here ...
    
      start := (start+20)//200
      end := (end+20)//200
    

    This is called a ring buffer. Same thing I use in Snake, my entry in the Smile game competition.
  • stefstef Posts: 173
    edited 2011-11-08 00:12
    Thanks for all the reaktions.

    I implemented last night the longmove in my code and it works like a charm.

    @Magio2
    No it is not to keep the cog busy. The diggerent var are used in diffrent parts of the code. For human it is easier to follow if i let the contend follow the flow. It is less complex to create smaller code if shifting then do complex coding and keep the content fix. If in later situation you need to trouble shoot it is faster pin pointed. it dous not mather that the cog is doing the shift if nothing els is needed to do.
    Beside that it is the programmers freedom to create his program like he thinks is best fit. I created a code part to programm the PROP over TCP/IP to do firmware updates over the network. That is taken a part of the eprom space. That is why i 'm more interested in smaller coding than in keeping th cog busy.
    I also want to learn more new things in the prop. that kan be small things like longmove. I never used it befor but now it was a case where it was possible.

    stef
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-11-08 05:34
    @stef:
    Looks like you feel a bit offended by "And by the way ... what's the reason for moving the data besides keeping the COG busy?". It was meant as a joke and not as offense.

    You say: "I also want to learn more new things in the prop". That's why I mentioned the other way to do it. Maybe somewhen in the future a ring buffer is a better fit - maybe even now and you did not realize so far.
    My guesstimate is that a longmove needs longer than those 2 instructions for calculating start and end. So, if you say you access the data from several places this might mean that you access it from different COGs? In this case you have to synchronize the access of the arrays, otherwise your other COGs might see an inconsistent state. This can be hard to find bugs. Shifting start and end instead of a full movement can then minimize the time where other COGs have to wait.
    About "creating smaller code": Ok ... if you count bits ;o) No, serious again ... that's what I call the ying and yang of programming. Most times you have the choice: Fast code needs more memory (in terms of bigger data structures or more code...) and smaller code is slower (function calls need time...) ... as I said not always, but often.
  • tonyp12tonyp12 Posts: 1,951
    edited 2011-11-08 07:49
    MagIO2 is right, learning the ringbuffer is necessary step in becoming a good programmer.
    Move the pointer not the data is the correct way to do it.
    You may have plenty of time left in this code but it's always good keep the cogs workload to a minimum if it's possible.

    So think of a circle with 200 slots: var A[200]
    0-19 would replace A1
    20-39 would replace A2

    So you can move the pointer up 20 slots each time
    and just check for pointer >200 and reset pointer to 0 (or use modulo 200 with //)

    I also used the ring buffer for my '94 Amiga I-Worm game, where the tail gets deleted slighty slower than the head.
    And the the maximum buffer I would need would be the 40*30 playing area and not 2 new bytes for max play time.
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-11-08 08:02
    In general, it is more efficient to use a ring buffer than shifting the data. However, a LONGMOVE in Spin doesn't use a lot of cycles for a small number of longs, so there may be situations where shifting data would be more efficient than a ring buffer. A ring buffer requires using read and write indices, incrementing them and masking the indices or limiting them to the buffer size. Depending on how the buffer is used, a LONGMOVE of 100 longs may actually be moe efficient in Spin.

    EDIT: A LONGMOVE of 100 takes about 4,200 cycles. It takes about 2,600 cycles to increment read and write pointers and mask them off. So a ring buffer is more efficient for 100 longs. The break-even point is around 50 longs. I didn't consider how the buffer is actually accessed, which could make the ring buffer mode less efficient for 100 longs.
  • stefstef Posts: 173
    edited 2011-11-08 14:40
    Hi Magio2

    I'm not at all offended. I like the answers in this forum. It give's different looks at possabilities. I also looked at your proposal. Thanks for pointing out that possabillity.
    I'm not at all at level to discuss good or wrong way to deal with something in spin. My level of experiance is not high enough for that.
    I deal every day with differand problems and are trying to resolve them. Learning in the proces.
    So pleas do not stop pointing out more posibilities when asked a question.
    I also hope you understand that programming is kind like art. It is a translation of the man programming and trying to resolve the problem. Thier will be always people thinking that thier is a better way. Even if his way is also working fine. So I find it a bit like art, they are also differend some you like and other you don't.
    I find somethimes programs not created by me difficult to read, and understand. Even if you understand the spin code as it is by itself you also need to capture the flow and reason behind it.
    Perhaps it is also the language englisch. As you will probably figured out by yourself it is not my native language. That why I type so many spelling faults. It is also not as easy to get the impression wright. But I try.

    thanks again to all for reackting on this forum. I like to use and read it. Keep it up.

    stef
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-11-09 00:06
    I'm sorry, but I disagree with "I also hope you understand that programming is kind like art" - after really thinking about your statement.

    Art for me is the freedom to do whatever you want to in whatever way you want to because the end-result of art should please your eyes, should touch your mind, should inspire you .... There is no functional reason for art, it does not have to work and it does not have to be optimized.

    To say "programming is like art" is the same as saying "it's magic" to a physicist who's showing you an experiment - for a novice it looks like magic, but it's actually not - programming might look like art, but it's actually not!
    Programming is a master craftmanship - same as the japanese blacksmith who builds katanas. For good programming you need to know as much as possible ... ring buffers, gap buffers, linked lists, hashing, recursion, iteration, data structures, libraries, how does the mikrocontroller work ..... You need to know the advantages and disadvantages of all these things.
    And according to the project you put together the right things to make the program work. And even if there is an unlimited number of ways to do the same thing, there is only a limited amount of ways to have the optimal result. So, programming means to find such an optimum (even if it's only a local optimum*1) ;o).

    The point is that the definition of optimum is different from project to project. Let's say you want to build a GPS-logger. If you want to build it for a car (connected to the car-battery) or totally portable (using one AAA cell) adds different views of the optimal result to the project. Connected to a car battery means you don't have to worry to much about power consumption. Back to your original question: use longmove for this - fine! For the portable version it would be better to pick the fastest code possible and rather spend the time you win with it in a waitcnt to save power. But power is only one part of the problem-domain!
    Some things that add possibly totally different needs to a project:
    * physical limits of the uC
    * requirements from the project (eg. sample rate, power consumption, usability ... )
    * requirements from the company/client (eg. reuseable code, maintainable code, easy to understand code, usage of standard products, using open source, price tag ... )



    *1) local optimum means that you found the optimum that can be reached with your personal knowledge. And that's why I think answers to such questions should also point into different directions. Maybe it points you to another local optimum and with enough such input you could possibly reach a global optimum.
Sign In or Register to comment.