EmbeddedRelated.com
Forums

Code execution Speed (Rowley vs CC)

Started by Richard May 25, 2008
Not only is context removed, now facts are changed as the bullying
sickos come out and viciously attack me, not the original poster. How
interesting.

The facts are a posting was made with poor quality information, such
as typical from a newbie. The original poster did NOT indicate they
were using the keyword 'volatile'. I responded at a level appropriate
to the level presented, not with the sick contempt and outrage at
the 'ignorant, who fail to follow rules, and present the sicko
experts with an opportunity to demonstrate their
heroic 'righteousness', like junkies needing a fix.

I have no intention of being drawn into an irrelevant 'debate' in
which every statement I make will have context removed, facts altered
and be twisted and distorted to suit the world view of sick
unpleasant personalities.

Why waste time reinforcing the very valid view that many experts and
techies as manipulative loser sick emotional cripples playing a
righteous heroic victim game and craving the respect and adoration of
those they despise and regard with contempt? It gives me the creeps.

Get real.

John Heenan

--- In m..., "microbit" wrote:
>
> When I saw your initial comment John, I thought "Wow, that's gonna
insult all compiler writers"
> (Mainly because your 'achieving benchmarks' comment is complete
crap). I'd rather be an innocent
> bystander, but your reaction is too far left field I thought.
> In fact, I'm surprised no other tool vendors have attempted to get
all your 8 cylinders firing
> again.
>
> > The isssue of not using volatile with a delay loop is very well
known
> > for those who are experienced.
>
> Richard, the OP, enunciated that he WAS using volatile qualifiers,
so the last squirm of "missing
> context" is rather futile IMO.
>
> I'm all for standing up for the 'underdog' and/or the righteous.
But first of all they have to be
> correct and/or properly informed - you're not.
> The bottom line is that YOU raped context. You took Richard's post
as an excuse/disguise to lash
> out at C tool vendors.
>
> I have my own gripes - like many - but if you have one, come
straight out with it and don't
> perform some bumbling charade many can look through (and don't get
huffy when they do).
>
> In other words (in case you still don't get it), respond to Richard
to help him, not to make a
> fool of yourself. It helps no one, including yourself.
>
> -- Kris
>
> -----Original Message-----
> From: m... [mailto:m...] On
Behalf Of John Heenan
> Sent: Monday, 26 May 2008 10:22 PM
> To: m...
> Subject: [msp430] Volatile and delay loops
>
> With the context reinserted, instead of removed to make spiteful
> personal attack on me from some of the most boring, unimaginative,
> spiteful and unemployable people on the planet, your compiler with
> optimisation turned on is liable to turn, contrary to your
> instructions
> {
> unsigned char x=0xFF;
> while(xx--);
> }
> into absolutely nothing unless you use instead
>
> {
> volatile unsigned char x=0xFF;
> while(xx--);
> }
>
> The isssue of not using volatile with a delay loop is very well
known
> for those who are experienced.
>
> John Heenan
>

Beginning Microcontrollers with the MSP430

Well, I might as well 'remove context' one more time to actually make sense :

> The original poster did NOT indicate they were using the keyword 'volatile'.

Is that so ? What's this then (verbatim, all context :-) :

> John,
> I understand C code can be compiled different ways. The difference in speed is huge
> throughout the code, like a system clock being configured differently.
>
> Yes, the loop variables are all declred volatile and are not being optimized away.
>
> Rich

Take a 'Lude, dude.
This constitutes my last comment in this thread.

PS : Your last paragraph below makes no sense whatsoever.

-- Kris
-----Original Message-----
From: m... [mailto:m...] On Behalf Of John Heenan
Sent: Tuesday, 27 May 2008 1:38 PM
To: m...
Subject: [msp430] Re: Volatile and delay loops

Not only is context removed, now facts are changed as the bullying
sickos come out and viciously attack me, not the original poster. How
interesting.

The facts are a posting was made with poor quality information, such
as typical from a newbie. The original poster did NOT indicate they
were using the keyword 'volatile'. I responded at a level appropriate
to the level presented, not with the sick contempt and outrage at
the 'ignorant, who fail to follow rules, and present the sicko
experts with an opportunity to demonstrate their
heroic 'righteousness', like junkies needing a fix.

I have no intention of being drawn into an irrelevant 'debate' in
which every statement I make will have context removed, facts altered
and be twisted and distorted to suit the world view of sick
unpleasant personalities.

Why waste time reinforcing the very valid view that many experts and
techies as manipulative loser sick emotional cripples playing a
righteous heroic victim game and craving the respect and adoration of
those they despise and regard with contempt? It gives me the creeps.

Get real.

John Heenan

Paul Curtis:
> --- In m..., Andreas Koepke wrote:
>> Out of curiosity: why use volatile?
>>
>> One of the C books that I read recommended to write
>>
>> for(int c=0; c < 10; c++) {
>> ; /* notice the semicolon */
>> }
>>
>> for a delay loop. Is that still correct?
>
> The semicolon has no effect, it delimits a null statement. The loop can be optimized away
> completely. This is because c's scope is restricted to the for loop and, hence, its value is
> dead at the end of the for loop. Because it is dead and not volatile, data flow and
> dominator analysis reveals the code is dead. (Modern compilers use SSA or variants such
> as GSA and this loop just washes away as a by-product of PRE.)
>
> This is mildly technical for those that know nothing of compilers.
>
> -- Paul.
>

Thanks, it seems that this method applied to a specific compiler that
used the semicolon to recognize a delay loop. Oh well...
IAR's compiler uses a thing called __delay_cycles() where you can
specify how many cycles to kill. It must be a value known at compile
time. We use it to kill a millisecond. It's nice because you know it
won't change with their compiler updates, optimizer levels, etc.

Lloyd

--- In m..., Andreas Koepke wrote:
>
> Paul Curtis:
> > --- In m..., Andreas Koepke wrote:
> >> Out of curiosity: why use volatile?
> >>
> >> One of the C books that I read recommended to write
> >>
> >> for(int c=0; c < 10; c++) {
> >> ; /* notice the semicolon */
> >> }
> >>
> >> for a delay loop. Is that still correct?
> >
> > The semicolon has no effect, it delimits a null statement. The
loop can be optimized away
> > completely. This is because c's scope is restricted to the for
loop and, hence, its value is
> > dead at the end of the for loop. Because it is dead and not
volatile, data flow and
> > dominator analysis reveals the code is dead. (Modern compilers
use SSA or variants such
> > as GSA and this loop just washes away as a by-product of PRE.)
> >
> > This is mildly technical for those that know nothing of compilers.
> >
> > -- Paul.
> > Thanks, it seems that this method applied to a specific compiler that
> used the semicolon to recognize a delay loop. Oh well...
>

What a sick joke. Even the quote below to supposedly establish
context is contextually misleading. It is by no means the original
post. Even the quote establishes that the poster was replying to
something I posted before.

>From a factual perspective what has emerged is that Rowley appears to
use registers for variables that are declared volatile. While this
will help benchmarks, personally I find it bizarre. There is a good
argument this violates the C standard.

With regard to the last paragraphs. I read them out to someone before
I posted. They knew exactly what I meant, loved it and laughed. If
you think poor behaviour is not been noted, then think again. I guess
many of you are so self absorbed that you are clueless.

By the way consider a career in the public service. I am sure our
Orwellian 'Ministries of Truth' would love the way you alter facts.

John Heenan

--- In m..., "microbit" wrote:
>
> Well, I might as well 'remove context' one more time to actually
make
> sense :
>
> > The original poster did NOT indicate they were using the keyword
> > 'volatile'.
>
> Is that so ? What's this then (verbatim, all context :-) :
>
> > John,
> > I understand C code can be compiled different ways. The
difference
> > in speed is huge
> > throughout the code, like a system clock being configured
differently.
> >
> > Yes, the loop variables are all declred volatile and are not
being
> > optimized away.
> >
> > Rich
>
> Take a 'Lude, dude.
> This constitutes my last comment in this thread.
>
> PS : Your last paragraph below makes no sense whatsoever.
>
> -- Kris
> -----Original Message-----
> From: m... [mailto:m...] On
Behalf Of
> John Heenan
> Sent: Tuesday, 27 May 2008 1:38 PM
> To: m...
> Subject: [msp430] Re: Volatile and delay loops
>
> Not only is context removed, now facts are changed as the bullying
> sickos come out and viciously attack me, not the original poster.
How
> interesting.
>
> The facts are a posting was made with poor quality information, such
> as typical from a newbie. The original poster did NOT indicate they
> were using the keyword 'volatile'. I responded at a level
appropriate
> to the level presented, not with the sick contempt and outrage at
> the 'ignorant, who fail to follow rules, and present the sicko
> experts with an opportunity to demonstrate their
> heroic 'righteousness', like junkies needing a fix.
>
> I have no intention of being drawn into an irrelevant 'debate' in
> which every statement I make will have context removed, facts
altered
> and be twisted and distorted to suit the world view of sick
> unpleasant personalities.
>
> Why waste time reinforcing the very valid view that many experts and
> techies as manipulative loser sick emotional cripples playing a
> righteous heroic victim game and craving the respect and adoration
of
> those they despise and regard with contempt? It gives me the
creeps.
>
> Get real.
>
> John Heenan
>

John,

> From a factual perspective what has emerged is that Rowley appears to
> use registers for variables that are declared volatile. While this
> will help benchmarks, personally I find it bizarre. There is a good
> argument this violates the C standard.

And that argument is, of course, not presented. Your modus operandi is to
present something without any research or fact, just gut instinct (viz
"CrossWorks doesn't generate jump tabes" and "CCE uses GCC as its
compiler").

So, I'm looking for a direct reference to the ISO C standard which gives
substance to your argument and clearly demonstrates that CrossWorks violates
the standard in this instance.

Can do you that for us, John?

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors

On Mon, 2008-05-26 at 20:37 +0200, Andreas Koepke wrote:
> Out of curiosity: why use volatile?
>
> One of the C books that I read recommended to write
>
> for(int c=0; c < 10; c++) {
> ; /* notice the semicolon */
> }
>
> for a delay loop. Is that still correct?
>
> Thanks, Andreas
>

It looks like no one answered your question directly, and the discussing
forked.

When you write a statement like:

for(int c=0; c < 10; c++) {;}

When you finish the loop c = 10 (and then goes away because it was
declared in this block).

An optimizing compiler takes what you wrote and tries to produce the
same answer in the fewest machine cycles or smallest code.

So since no one is using c in the loop, the loop can be reduced to c 10. It produces the same result mathematically, in less lines of code
and faster.

Most people assume c is in memory, but it does not have to be. It can be
put in memory or it can be put in a register, (and if put in memory it
can be put anywhere the compiler wants, in general ram or on the stack)
it is up to the compiler. The compiler can put it in memory then copy it
to a register do a bunch of operations to it, then copy the final
results to memory. It does not matter as long as the answer is the same.
Anything the compiler can do to speed up the process and use fewer
instructions is fair game, as long as the answer is the same.

So replacing 

for(c=0; c < 10; c++) {;}

with

c = 10;

gives you the same mathematical result. So the optimizing compiler can
do it.
When you declare a variable as volatile, that tells the compiler, that
something else (not in that section of code) can change that variable
while you are working with it. Usually it is an interrupt. So you can
not assume you have full control over the variable in this section of
code. This slows it down a lot because you have to pull it from memory
and write it to memory each time you use it, in case an interrupt
changed it. You can not temporally use it in a register, because the
interrupt has no idea where it may be if it is not in the memory
location.

As a result if your code is
volatile int c; 
for(c=0; c < 10; c++) {;}

then it has to execute with c = 0, c = 1, ... to c = 10 because an
interrupt may occur in the middle of the loop and change c or use c. So
you can not assume c will be 10 at the end of the loop. The interrupt
may say c += 20; so the result depending on when the interrupt fired
could be be any number between 20 and 30 if the interrupt fired one time
during the loop. But it could fire 0 times or 100 times during the loop,
the compiler has no idea, so it can not take any steps to make the code
faster or smaller.

I hope that answers your question Andreas.

Kip
--
Kipton Moravec KE5NGX
"Always do right; this will gratify some people and astonish the rest."
--Mark Twain

On Wed, 28 May 2008 03:31:56 -0000, John wrote:

>What a sick joke. Even the quote below to supposedly establish
>context is contextually misleading. It is by no means the original
>post. Even the quote establishes that the poster was replying to
>something I posted before.

I think the gist is that Richard indicated (not in his first post on
the subject, but in one that was responding to your early post to him)
he was using the volatile keyword. His comment was, "Yes, the loop
variables are all decl[a]red volatile and are not being optimized
away." Richard, so far as I know, was already fully aware of the need
for volatile _before_ making his first post (on the subject of speed
differences between CC and Rowley in the specific case of speed
optimation and the code fragment Richard was discussing then.)
Microbit said as much to you, writing, "Richard, the OP, enunciated
that he WAS using volatile qualifiers, so the last squirm of 'missing
context' is rather futile IMO." Microbit was correct in that comment,
whether or not it was because of Richard's first post or a later one,
and didn't deserve the "bullying sickos" comment you made, which is
beginning to seem more a matter of psychological projection than
anything else.

>From a factual perspective what has emerged is that Rowley appears to
>use registers for variables that are declared volatile. While this
>will help benchmarks, personally I find it bizarre. There is a good
>argument this violates the C standard.

I'm no expert on C standards, just a sometimes interested reader of
them. But you should consider citing specifics from the relevant C90
or C99 standards documents or else we may be left guessing that you
mean to suggest from the above that "bizarre to John" == "violates the
C standard," an idea to which I think many of us may take some modest
exception -- let alone those responsible to actually write and
maintain c compilers.

Perhaps you didn't mean to write things exactly as you did above, but
you seem to be thinking (I can't speak for you, but it could be read
this way) that Rowley __always__ uses registers for volatile
variables. I don't think that is the case. The use of R15 in the
sample code that Richard posted for comparison purposes was a matter
of the specific DAG and basic block representations and then various
transformations applied, followed by other optimization steps.
Compilers are generally free to emit code that are semantically equal,
given the language specifications about that subject. Some compilers
will emit code that is "better" than others on various scales of
measure and they are also free to make topological transformations and
variable assignments that do not break semantic equality.

Placing an instance or parameter variable into a register instead of
placing it on a stack is generally (for c, anyway) a matter of
compiler choice.... so long as the instance values act as the language
says they should act. The use of R15 instead of 2(SP) isn't a matter
a c coder can specify. For whatever good or bad that may mean, this
detail of implementation is left to the compiler implementor.

You are permitted to suggest a register be used through the use of the
'register' keyword, but even then the compiler isn't required to obey
you. It's just a hint which the compiler may ignore or use, not an
order that must be obeyed. And there is no means by which you can
inform the compiler that it should _not_ use a register for a
parameter or instance variable (auto). That is not specifiable by a c
programmer, either by implication or explicit syntax.

I would suppose that the key argument you might make would be in
regard to the required _number_ of references/assignments or else by
discussing the _order_ in which these take place. But that wouldn't
be about whether or not a register was used.

Let's bring back Richard's post on the assembly generated by the two
compilers for { volatile int j; for( j= 0; j<1050; j++ ) ; }. But
let's rephrase the code slightly:

#define N (1050)
{
volatile int j;
for( j= 0; j < N; j++ )
;
}

This breaks down to:
j= 0; /* sequence pt .. assignment to 'j' must take place */
x:
if ( j < N ) /* sequence pt .. read of 'j' must take place */
j++; /* additional read of 'j', one assignment to 'j' */
goto x;

I'm not positive of my interpretation of 'volatile' and sequence
points here and I'm very much open to being corrected. But I read the
above as requiring, assuming that 'j' isn't modified by some external
event (which we are assuming here it is not):

1 assignment to 'j' due to 'j= 0'
1 read of 'j' due to first execution of condition
N alternated reads of and assignments to 'j' due to 'j++'
N reads of 'j' due to repeated execution of condition

Thus, given that 'j' starts out as 0 and that N is positive or zero:

N+1 assignments to 'j'
2N+1 reads of 'j'

And this sequence of events:

write 'j'
read 'j'
N*[ read 'j', write 'j', read 'j' ]

I believe that in the case of a volatile object like 'j', the last
store to it doesn't have to be included if there is no further read
taking place in the block. But that doesn't apply to the above case
as the conditional guarantees that there must always be a read of 'j'
as the last step. Also, the ordering must be preserved, as indicated.

This code was posted by Richard:

Code Composer:
-------------------------
mov #0, 2(SP)
cmp #1050, 2(SP)
jc L002
L001: inc 2(SP)
cmp #1050, 2(SP)
jnc L001
L002:

Note that in the above case the variable 'j' is allocated on the local
activation record (stack frame) and that a separate frame pointer
isn't being used, instead just relying upon the "known" position of SP
relative to the local variable for the given code fragment's instance
of execution. In other words, SP is pointing just past the local
variable and the code generator knows it.

I believe CC's code conforms. It performs N+1 assignments and 2N+1
reads and in the correct ordering.

Rowley:
-------------------------
mov #0, R15
L001: add #1, R15
cmp #1050, R15
jnc L001

In this case, R15 has been assigned to variable 'j', instead of a
stack location. That in itself isn't a problem. However, the
optimized code insists that N be at least 1 instead of at least 0
(okay, I suppose, given that it knows that N is greater than 0) and
performs N+1 assignments to 'j' and 2*N reads of 'j' ... which may be
off by one.

The sequence of events for Rowley's code seems to be (assuming N is
greater than 0, of course):

write 'j'
read 'j'
write 'j'
read 'j'
(N-1)*[ read 'j', write 'j', read 'j' ]

It may be possible to argue here that the required references and
ordering has not been preserved as required by the standard. I
haven't cited specifics, though, because my copy of the specification
leaves much to be desired in terms of interpretation here and it may
be better to let those who know the details well make the citations in
response to the above point.

But I can see a possible argument on this narrow ledge from my
neophyte understanding of the specifications I've read. (Note nothing
about the use of registers here.)

Jon

This is about as black and white as it can get with regard to
interpreting a standard which attempts to deal with the 'unknown'.

Paragraph 6 of Section 6.7.3 of the ISO C standard on 'Type
qualifiers' states "An object that has volatile-qualified type may be
modified in ways unknown to the implementation or have other unknown
side effects."

In simpler terms this tells a compiler DO NOT MAKE ANY ASSUMPTIONS. I
don't think I need to SPELL OUT why assigning ANY volatile declared
object to a register is certainly making assumptions about usage of
the variable.

Point proven. The naive go off thinking every other compiler is
inferior because using registers shortens code and improves
benchmarks.

With regard to 'jump tables'. Both CCE and IAR provide KNOWN ways to
generate jump tables. On enquiry Rowley was dismissive. If there was
a way of generating jump tables they weren't going to tell us. Rather
odd given that the MSP430 has some interrupt facilities that are
ideally suited to jump table use, aside from the enormous general
benefits of jump tables.

I did notice that a listing of ARM assembly code from C from the OPEN
SOURCE compiler USED by Rowley, that was posted on another group, did
produce a jump table. I was impressed and said this on the group.

Despite this don't think projects can be easily ported. Normal ARM
GCC linker command files are generated by Rowley only as long as they
are needed and then deleted.

There have been public comments about not been able to identify any
contributions made from Rowley to the development of the open source
compiler used by them. The cutting edge contributions, at the time,
were coming from www.opensourcery.com, which were well ahead of the
stultifying, politicised and bureaucratic snails pace the open source
GCC movement was working at.

Make up your own minds about what is doing on.

John Heenan
--- In m..., "Paul Curtis" wrote:
>
> John,
>
> > From a factual perspective what has emerged is that Rowley
appears to
> > use registers for variables that are declared volatile. While this
> > will help benchmarks, personally I find it bizarre. There is a
good
> > argument this violates the C standard.
>
> And that argument is, of course, not presented. Your modus
operandi is to
> present something without any research or fact, just gut instinct
(viz
> "CrossWorks doesn't generate jump tabes" and "CCE uses GCC as its
> compiler").
>
> So, I'm looking for a direct reference to the ISO C standard which
gives
> substance to your argument and clearly demonstrates that CrossWorks
violates
> the standard in this instance.
>
> Can do you that for us, John?
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>

Correction: the cutting edge ARM contributions are from
http://www.codesourcery.com/

John Heenan

--- In m..., "John Heenan" wrote:
>
> There have been public comments about not been able to identify any
> contributions made from Rowley to the development of the open
source
> compiler used by them. The cutting edge contributions, at the time,
> were coming from www.opensourcery.com, which were well ahead of the
> stultifying, politicised and bureaucratic snails pace the open
source
> GCC movement was working at.
>
> Make up your own minds about what is doing on.
>
> John Heenan