To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.robotics.rcx.nqcOpen lugnet.robotics.rcx.nqc in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / RCX / NQC / 203
202  |  204
Subject: 
Re: Sharing variables and using expressions (was Re: NQC 2.0 and some math questions
Newsgroups: 
lugnet.robotics.rcx.nqc
Date: 
Wed, 20 Oct 1999 00:56:40 GMT
Viewed: 
2526 times
  
The optimization was intentional (and quite a lot of work, actually).  I
know it breaks with multiple tasks, but I was more concerned with keeping
the variable pool from being cluttered with temporaries.  With only 32
vars to use, its quite easy to run out if every expression must first
evaluate into a temp, then assign to the destination.

I considered adding a #pragma to control this, but then figured that
anyone savvy enough to use the #pragma would also be savvy enough to work
around the problem another way.

I know this isn't ideal, but without a stack its really difficult to do
things "by the book".

This does warrant additional discussion in the manual, so I will add it
when I get some free time.

Dave Baum


In article <FJv8wM.99v@lugnet.com>, "Robert Munafo"
<munafo@gcctechNO.SPAMcom> wrote:

I have discovered a somewhat non-intuitive feature of NQC (in my version, at
least, which is pre-2.0)

The statement:

var = (20 * var) / 21;

gets compiled into the following:

MUL var, 20   ; var = var * 20
DIV var, 21   ; var = var / 21

rather than the more standard:

SET tmp, var  ; tmp = var
MUL tmp, 20   ; tmp = tmp * 20
DIV tmp, 21   ; tmp = tmp / 21
SET var, tmp  ; var = tmp

The reason this matters is that the value of "var" might be read by another
task. The traditional rules for inter-process communication via shared
variables allow simple (non-mutex) variable sharing as long as there is at most
one task that writes to the variable. (If there is more than one writing task,
semaphores must be used).

However, this simple rule relies on some more fundamental (and implied) rules
known mainly to compiler writers, namely:

- each occurrance of a variable in a RHS (right-hand-side) context generates
at most one (atomic) read access, and

- each occurrance of a variable in an LHS (left-hand-side) context generates
at most one (atomic) write access.

Usually implementation of these rules is easy because there is a stack, some
registers, and/or some other type of storage that is saved and restored on each
task context switch. NQC failure to comply is understandable in view of the
restrictions of the firmware.

The good news is that programmers using NQC can avoid this problem (if they
wish) by explicitly breaking their expressions up into pieces that compile into
a single firmware opcode, thereby preventing NQC from second-guessing. Such a
programmer would explicitly rewrite my example as:

tmp = var;
tmp *= 20;
tmp /= 21;
var = tmp;

There are additional inter-task issues with temp variables, which I assume NQC
avoids. For example, a seperate pool of temp variables must be allocated for
each task, lest two tasks interfere with one another by sharing the same temp
variable. If you are concerned about such issues, you could rewrite all of your
expressions as single operations and allocate all your temp variables
explicitly. Of course, you need to follow the same rules, and make sure to give
each task its own set of temp variables.

In lugnet.robotics.rcx.nqc, Dave Baum writes:
In article <37f16547.6612368@lugnet.com>, marcob@equalis.it wrote:

x = y % z

is equivalent to (where w is an temporary integer):

w = y / z;
x = y - z * w;


That's exaclty what I was thinking of doing.  Originally, the compiler had
no way of allocating temp variables which is why code for % couldn't be
emitted.  The temp allocator is now pretty good, so I could emit the above
sequence, but it just didn't occur to me until a few days ago.

There is one subtle problem.  The operations above won't happen
atomically, so there are some concurrency issues.  To be completely safe,
I'd have to latch both y and z into temps as well.  Without this, some
truly weird stuff can happen.  For example, lets say that intially y is a
multiple of z, and then you decrement y in-between the computation of w
and x.  The result will be that x is negative.  This is a result that is
inconsistient with the decrement happening either before or after the
entire mod calculation.

My personal feeling on this, however, is that if you're running around
changing y amd z in one task while calculating with them in another,
you're just asking for trouble.

- Robert Munafo                           http://www.mrob.com/
LEGO: TC+++(8480) SW++ #+ S-- LS++ Hsp M+ A@ LM++ YB64m IC13

--
reply to: dbaum at enteract dot com



Message has 2 Replies:
  Re: Sharing variables and using expressions (was Re: NQC 2.0 and some math questions
 
(...) I appreciate this -- that's what the "Not Quite" is all about. As long as you explain things well, I think this kind of compromise is the right way. (25 years ago, 20-Oct-99, to lugnet.robotics.rcx.nqc)
  Re: Sharing variables and using expressions (was Re: NQC 2.0 and some math questions
 
Thanks, Dave! It will be good to have that in the manual, because it is a very confusing behavior that is difficult to track down. Variables take on values that are completely different from the values that the programmer is setting them to. Most (...) (25 years ago, 1-Nov-99, to lugnet.robotics.rcx.nqc)

Message is in Reply To:
  Sharing variables and using expressions (was Re: NQC 2.0 and some math questions
 
I have discovered a somewhat non-intuitive feature of NQC (in my version, at least, which is pre-2.0) The statement: var = (20 * var) / 21; gets compiled into the following: MUL var, 20 ; var = var * 20 DIV var, 21 ; var = var / 21 rather than the (...) (25 years ago, 19-Oct-99, to lugnet.robotics.rcx.nqc)

16 Messages in This Thread:




Entire Thread on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact

This Message and its Replies on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR