![]() |
||
|
This board is for PLC Related Q&A ONLY. Please DON'T use it for advertising, etc. |
||
| ||
New Here? Please read this important info!!!
|
|||||||
![]() |
If you're really looking to learn about PLCs, you NEED our book... "Your Personal PLC Tutor - A Guide to Understanding PLCs" Easy to read and uses 'plain' language!
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Member
|
The bit hack challenge
Time for another bit hack puzzle.
The following code is how a recycling counter (such as one might use in indexing through an array) is usually done: I := 1+1 If I > Max_I then I:=0 It is implemented in a for/next or do/while loop. This necessitates a comparison and branching. However, if for example you want to index a 4 item array, 0 thru 3, then this works really well. I := (I+1) & 3 This code counts 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2 .... The general form works for any 2n counts where counting begins at 0 and goes to to 2n-1 I:= (I+1) & (2n-1) The advantage is that no branching or comparison is involved, as a result it will execute very fast when 2n-1 is a constant. Now suppose that someone wanted to use some other number. For example, what bit hack will cycle 0 through 5? The challenge: Pick any integer not equal to (2n-1) and develop a bit hack that can be expressed as a single equation that will count up from 0 to that number and then recyle to 0, or count down from that number to 0 and then reset to that number.
__________________
True craftsmanship is only one more power tool away. Last edited by Alaric; May 12th, 2009 at 05:30 PM. |
|
|
|
#2 |
|
Member
|
The obvious answer is to use the MOD operator.
i:=(i+1) mod n; Now I assume you want something with shifts, ands and ors.
__________________
"Living is easy with eyes closed, misunderstanding all you see...." Strawberry Fields Forever, John Lennon |
|
|
|
#3 |
|
Member
|
Well, it is supposed to be a challenge...
![]() Besides, MOD involves division, (unless there is binary trick I don't know) and we know how you feel about division.
__________________
True craftsmanship is only one more power tool away. Last edited by Alaric; May 12th, 2009 at 05:54 PM. |
|
|
|
#4 |
|
Member
|
Were you expecting a different answer?
I would frown on methods other than the AND and IF THEN methods you have already shown. A lot depends on the application.
__________________
"Living is easy with eyes closed, misunderstanding all you see...." Strawberry Fields Forever, John Lennon |
|
|
|
#5 |
|
Member
|
> I would frown on methods other than the
> AND and IF THEN methods you have already shown. Why would you frown upon a=(a+1)%x? That's extremely common in, say, FIFO implementations in 'real' languages. Performance is not an issue on most modern processors, and will exceed the IF...THEN case in many situations.
__________________
Mike Granby President Red Lion Controls Check out our new software at www.crimson3.com |
|
|
|
#6 | ||||
|
Member
|
Look at your Icon and then mine. That says it all.
Quote:
Quote:
Quote:
Quote:
Show me!!! As Alaric pointed out, the MOD operator uses a divide instruction or must go through the divide process. This usually takes a one clock cycle for every bit in the divisor let alone the check for divide by 0 and to take the absolute value if required even if done in hardware. The if-then method usually takes about 5 clock cycles, one for the compare and 4 to make the jump. Many modern risc machines, like ARMs, do not have a divide instruction. However, ARMs have a compare with conditional execution that makes the compare method the fastest method. BTW, I like your G3xx because they can easily communicate with our controller and it is unique in that it can read/write blocks of data from our plot buffers as opposed to other HMIs, that can only attempt to read one tag at regular intervals to make a plot with a lot of sample jitter.
__________________
"Living is easy with eyes closed, misunderstanding all you see...." Strawberry Fields Forever, John Lennon |
||||
|
|
|
#7 |
|
Member
|
I didn't realize that the if-then takes just five clock cycles - thought it would be more with the jump. I might depend on how efficient the compiler is. I had a teacher back in college that used to have contests to see who could write the fastest code, getting above a certain benchmark could mean getting to skip an exam, so I had incentive to avoid branching anywhere it was possible. That may not have necessarily instilled the best programming habits in the students however it did get us to think creatively.
Normally I don't worry about those things, the time simply spent isn't worth the extra CPU time - but I do enjoy a good bit hack challenge to tinker with from time to time. I've got a couple of machine right now each with a ControlLogix, Delta RMC and a G306 on it. Right now the G306 talks only to the CLX, but I've been itching to play with it talking to the RMC. I haven't had the time on the machine since, production wanted it, I guess the factory has to make money. Imagine that.
__________________
True craftsmanship is only one more power tool away. |
|
|
|
#8 |
|
Member
|
It obviously depends on the processor, but if it has a hardware divider the cost of the pipeline stall from the branch can be higher than the cost of the division, especially since the branch is taken most time. (The ARM can use its conditional execution features to avoid the jump, which is even better.) Of course, the real answer is to code using mod and use 2^n buffer sizes, knowing that the compile will reduce the mod to an and, and that you won't have to worry about breaking anything if your buffer sizes change.
__________________
Mike Granby President Red Lion Controls Check out our new software at www.crimson3.com |
|
|
|
#9 | |||||
|
Member
|
Quote:
Quote:
Quote:
Quote:
Quote:
Modern CPUs also have branch predicting or a compile time optimization that optimizes the jump in a loop. This minimizes the number of pipeline stalls.
__________________
"Living is easy with eyes closed, misunderstanding all you see...." Strawberry Fields Forever, John Lennon |
|||||
|
|
|
#10 |
|
Member
|
|
|
|
|
#11 |
|
Member
![]() Join Date: Mar 2007
Location: MN
Posts: 123
|
I = (I + 1) & ((I - 7) >> 16)
Where the 7 is the value to count up to and 16 is half the size of the bit register. This bit hack utilizes a two’s compliment negative number as a mask which will reset the count when it becomes non-negative. The hack will only work for numbers small enough to be represented using the lower half of the bit register. For example, 65535 or less for a 32 bit register. As Peter mentioned, this hack would be a head scratcher if found in someone else’s program, and would generally be frowned upon. |
|
|
|
#12 |
|
Member
|
I like it, good for you Brownhat!
This just needs to be documented so that it is a well known trick. On a TI TMSC33 a compare a jmp will take 5 clock cycles and your trick will take 4 clock cycles at best. I would need analyze this to make sure that the 7 can be subtracted from the I on the next clock cylinder without stalling the pipeline. Also, the shift right must happen in one clock cycle so the CPI must have a barrelshifter. If there is a pipeline stall then the tie goes to the obvious and straight forward method. Also, as I pointed out the TI can often to the jump without wasting clock cycles by using a delayed jump.
__________________
"Living is easy with eyes closed, misunderstanding all you see...." Strawberry Fields Forever, John Lennon |
|
|
|
#13 | |
|
Member
|
Quote:
I was being so dense about this one that I didn't believe it would work until after I dumped it into a bash script on my linux box and saw it with my own eyes. It still took me stepping through the example one number at a time until the whole 'reset the count when it becomes non-negative' thing clicked. |
|
|
|
|
#14 | |
|
Member
|
Quote:
![]() @Brownhat Very clever.
__________________
Just because you can doesn't mean that you should... |
|
|
|
|
#15 |
|
Member
|
Nice one Brownhat. I've been playing with this problem off and on for several days and hadn't come up with a solution yet. I was starting to wonder if a general case solution even existed.
__________________
True craftsmanship is only one more power tool away. |
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|
Similar Topics
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Moving data into a bit shift | josepa | LIVE PLC Questions And Answers | 2 | October 17th, 2006 08:37 AM |
| S7 Indirect bit addressing | curlyandshemp | LIVE PLC Questions And Answers | 1 | October 4th, 2006 01:40 AM |
| 10 Bit Encoder Decoder/ GE90-30 | Control Freak | LIVE PLC Questions And Answers | 6 | July 12th, 2005 11:28 AM |
| PID - MicroLogix Temperature Control | Peter Nachtwey | LIVE PLC Questions And Answers | 112 | October 11th, 2004 11:18 AM |
| 16 bit input in word address | rjanociak | LIVE PLC Questions And Answers | 3 | May 15th, 2002 11:43 AM |