Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old January 11th, 2006, 09:46 AM
rodneys@gmx.de
Guest
 
Posts: n/a
Default Memory access optimization

Hi,

please take a look to this sample code:

class MyClass {
private:
static int length ;
public:
static void setLength(int newLength) ;
void do() ;
}

int MyClass::length ;

void MyClass::setLength(int newLength) {
length=newLength ;
}

void MyClass::do() {
for(int i=0;i<length;i++) {
// some simple floating point additions and multiplications ...
}
}

I expected that the compiler (Microsoft EVC 4 for ARM, full
optimization)
would optimize the for-loop of the method "do" to
register int t=length ;
for(int i=0;i<t;i++) {
...
}
But this does not happen. Instead, the generated machine code
refetches "length" in each iteration of the for-loop. Why?
Does the compiler "fear" that another thread could call "setLength"
while the for-loop runs? "length" is *not* declared volatile.

Is there a formal specification how long a compiler is allowed to cache
non-local variables in registers? For example, can code like
a = length ;
b = length ;
always be expected to be optimized to
register int t=length ;
a=t ;
b=t ;
?

rs

  #2  
Old January 11th, 2006, 01:05 PM
Thomas Maier-Komor
Guest
 
Posts: n/a
Default Re: Memory access optimization

rodneys@gmx.de wrote:[color=blue]
> Hi,
>
> please take a look to this sample code:
>
> class MyClass {
> private:
> static int length ;
> public:
> static void setLength(int newLength) ;
> void do() ;
> }
>
> int MyClass::length ;
>
> void MyClass::setLength(int newLength) {
> length=newLength ;
> }
>
> void MyClass::do() {
> for(int i=0;i<length;i++) {
> // some simple floating point additions and multiplications ...
> }
> }
>
> I expected that the compiler (Microsoft EVC 4 for ARM, full
> optimization)
> would optimize the for-loop of the method "do" to
> register int t=length ;
> for(int i=0;i<t;i++) {
> ...
> }
> But this does not happen. Instead, the generated machine code
> refetches "length" in each iteration of the for-loop. Why?
> Does the compiler "fear" that another thread could call "setLength"
> while the for-loop runs? "length" is *not* declared volatile.
>
> Is there a formal specification how long a compiler is allowed to cache
> non-local variables in registers? For example, can code like
> a = length ;
> b = length ;
> always be expected to be optimized to
> register int t=length ;
> a=t ;
> b=t ;
> ?
>
> rs
>[/color]

rule of thumb is to cache any global variable in a local variable to
ease optimization for the compiler. If a register is available, it will
be allocated for the local variable. If none is available, the local
varialbe will most likely be allocated on stack and therefore will most
likely have a better cache behaviour than its global counterpart. The
compiler might even be capable of eliminating the local variable.

I cannot say what the reason for missing optimization is your case,
because you omitted the contents of the for loop. But I recomend to
allocate a local variable that is the copy of the object attribute.

HTH,
Tom
  #3  
Old January 11th, 2006, 01:25 PM
mlimber
Guest
 
Posts: n/a
Default Re: Memory access optimization

rodneys@gmx.de wrote:[color=blue]
> Hi,
>
> please take a look to this sample code:
>
> class MyClass {
> private:
> static int length ;
> public:
> static void setLength(int newLength) ;
> void do() ;
> }
>
> int MyClass::length ;
>
> void MyClass::setLength(int newLength) {
> length=newLength ;
> }
>
> void MyClass::do() {
> for(int i=0;i<length;i++) {
> // some simple floating point additions and multiplications ...
> }
> }
>
> I expected that the compiler (Microsoft EVC 4 for ARM, full
> optimization)
> would optimize the for-loop of the method "do" to
> register int t=length ;
> for(int i=0;i<t;i++) {
> ...
> }
> But this does not happen. Instead, the generated machine code
> refetches "length" in each iteration of the for-loop. Why?
> Does the compiler "fear" that another thread could call "setLength"
> while the for-loop runs? "length" is *not* declared volatile.
>
> Is there a formal specification how long a compiler is allowed to cache
> non-local variables in registers? For example, can code like
> a = length ;
> b = length ;
> always be expected to be optimized to
> register int t=length ;
> a=t ;
> b=t ;
> ?
>
> rs[/color]

There is no formal specification for such optimizations in the
Standard. You might be better off posting in Microsoft-specific group
where more of their experts lurk. Several such groups are listed in
this FAQ:

http://www.parashift.com/c++-faq-lit...t.html#faq-5.9

Cheers! --M

  #4  
Old January 11th, 2006, 02:15 PM
rodneys@gmx.de
Guest
 
Posts: n/a
Default Re: Memory access optimization

> There is no formal specification for such optimizations in the[color=blue]
> Standard. You might be better off posting in Microsoft-specific group
> where more of their experts lurk. Several such groups are listed in
> [...][/color]

I know that it may be a MS-specific thing but I wanted to know what
c.l.c++ thinks about it. Do you agree with me that nothing in the specs
prevents the compiler from doing the optimization unless the variable
is declared volatile?

rs

  #5  
Old January 11th, 2006, 11:45 PM
David Harmon
Guest
 
Posts: n/a
Default Re: Memory access optimization

On 11 Jan 2006 06:00:59 -0800 in comp.lang.c++, rodneys@gmx.de
wrote,[color=blue]
>I know that it may be a MS-specific thing but I wanted to know what
>c.l.c++ thinks about it. Do you agree with me that nothing in the specs
>prevents the compiler from doing the optimization unless the variable
>is declared volatile?[/color]

I think you are right.


  #6  
Old January 12th, 2006, 12:05 AM
Dave Townsend
Guest
 
Posts: n/a
Default Re: Memory access optimization


<rodneys@gmx.de> wrote in message
news:1136988059.744127.36960@g14g2000cwa.googlegro ups.com...[color=blue][color=green]
> > There is no formal specification for such optimizations in the
> > Standard. You might be better off posting in Microsoft-specific group
> > where more of their experts lurk. Several such groups are listed in
> > [...][/color]
>
> I know that it may be a MS-specific thing but I wanted to know what
> c.l.c++ thinks about it. Do you agree with me that nothing in the specs
> prevents the compiler from doing the optimization unless the variable
> is declared volatile?
>
> rs
>[/color]

Why don't you make the length variable a local and see what MSVC does ?
Although "length" is not declared as voltaile, in typical MS manner, they
might
have tried to anticipate that you might be modifying "length" in another
thread
and so get the value each iteration of the loop.


  #7  
Old January 12th, 2006, 12:25 AM
Bo Persson
Guest
 
Posts: n/a
Default Re: Memory access optimization


"Dave Townsend" <datownsend@comcast.net> skrev i meddelandet
news:_KmdnUZI64KhB1jenZ2dnUVZ_tSdnZ2d@comcast.com. ..[color=blue]
>
> <rodneys@gmx.de> wrote in message
> news:1136988059.744127.36960@g14g2000cwa.googlegro ups.com...[color=green][color=darkred]
>> > There is no formal specification for such optimizations in the
>> > Standard. You might be better off posting in Microsoft-specific
>> > group
>> > where more of their experts lurk. Several such groups are listed
>> > in
>> > [...][/color]
>>
>> I know that it may be a MS-specific thing but I wanted to know what
>> c.l.c++ thinks about it. Do you agree with me that nothing in the
>> specs
>> prevents the compiler from doing the optimization unless the
>> variable
>> is declared volatile?
>>
>> rs
>>[/color]
>
> Why don't you make the length variable a local and see what MSVC
> does ?
> Although "length" is not declared as voltaile, in typical MS manner,
> they
> might
> have tried to anticipate that you might be modifying "length" in
> another
> thread
> and so get the value each iteration of the loop.[/color]

Yes. The length is globally accessible through the public static
function setLength. To be able to cache the length, the compiler must
first prove that no one is ever calling setLenght while the loop runs.

That's hard to do in the general case, so they have obviously not
bothered.


Bo Persson


  #8  
Old January 12th, 2006, 01:05 PM
rodneys@gmx.de
Guest
 
Posts: n/a
Default Re: Memory access optimization

> Yes. The length is globally accessible through the public static[color=blue]
> function setLength. To be able to cache the length, the compiler must
> first prove that no one is ever calling setLenght while the loop runs.[/color]

As already discussed above, the specs don't force the compiler
to prove anything, do they?

Ramin

  #9  
Old January 12th, 2006, 01:35 PM
rodneys@gmx.de
Guest
 
Posts: n/a
Default Re: Memory access optimization

> Why don't you make the length variable a local and see what MSVC does ?

First thing I tried. As expected, the local variable is kept in a
register
(plenty of free registers in the ARM processor).
[color=blue]
> Although "length" is not declared as voltaile, in typical MS manner, they
> might have tried to anticipate that you might be modifying "length" in
> another thread and so get the value each iteration of the loop.[/color]

As an experiment, I removed the setter-method and initialized the
variable
via
static MyClass::length=10 ;
so that the variable is never write-accessed in the code. No difference
:-(

I suppose that optimization on global data is generally very difficult
in languages like C/C++ where the compiler has to assume that you can
modify any variable indirectly with some pointer arithmetic+type casts.

Ramin

  #10  
Old January 12th, 2006, 09:15 PM
Bo Persson
Guest
 
Posts: n/a
Default Re: Memory access optimization


<rodneys@gmx.de> skrev i meddelandet
news:1137070375.845667.29160@g44g2000cwa.googlegro ups.com...[color=blue][color=green]
>> Yes. The length is globally accessible through the public static
>> function setLength. To be able to cache the length, the compiler
>> must
>> first prove that no one is ever calling setLenght while the loop
>> runs.[/color]
>
> As already discussed above, the specs don't force the compiler
> to prove anything, do they?[/color]

Yes, they do. Using volatile prevents the compiler from keeping the
value in a register. Not using volatile doesn't automatically allow
caching. The compiler must first make sure that the value is not
updated any other way. If the variable is global, or accessible
through a public function, that is hard.

Consider this code:

int i;

void f(int& j)
{
for (i = 0; i < 10; i++)
j = i;
}

int main()
{
int k;

f(k);
f(i);

}

What happens for f(k) ?
What happens for f(i) ?

Does that affect the optimizations possible for the function f()? It
sure does!


Bo Persson






  #11  
Old January 12th, 2006, 09:25 PM
Bo Persson
Guest
 
Posts: n/a
Default Re: Memory access optimization


"Bo Persson" <bop@gmb.dk> skrev i meddelandet
news:42nub8F1k26mlU1@individual.net...[color=blue]
>
> <rodneys@gmx.de> skrev i meddelandet
> news:1137070375.845667.29160@g44g2000cwa.googlegro ups.com...[color=green][color=darkred]
>>> Yes. The length is globally accessible through the public static
>>> function setLength. To be able to cache the length, the compiler
>>> must
>>> first prove that no one is ever calling setLenght while the loop
>>> runs.[/color]
>>
>> As already discussed above, the specs don't force the compiler
>> to prove anything, do they?[/color]
>
> Yes, they do. Using volatile prevents the compiler from keeping the
> value in a register. Not using volatile doesn't automatically allow
> caching. The compiler must first make sure that the value is not
> updated any other way. If the variable is global, or accessible
> through a public function, that is hard.
>
> Consider this code:
>
> int i;
>
> void f(int& j)
> {
> for (i = 0; i < 10; i++)
> j = i;
> }[/color]

Ok, this was a bad example. Change the line to j = 1; to show the
problem with f(i).
[color=blue]
>
> int main()
> {
> int k;
>
> f(k);
> f(i);
>
> }
>
> What happens for f(k) ?
> What happens for f(i) ?
>
> Does that affect the optimizations possible for the function f()? It
> sure does!
>
>
> Bo Persson
>[/color]


  #12  
Old January 12th, 2006, 09:35 PM
mlimber
Guest
 
Posts: n/a
Default Re: Memory access optimization

Bo Persson wrote:[color=blue]
> <rodneys@gmx.de> skrev i meddelandet
> news:1137070375.845667.29160@g44g2000cwa.googlegro ups.com...[color=green][color=darkred]
> >> Yes. The length is globally accessible through the public static
> >> function setLength. To be able to cache the length, the compiler
> >> must
> >> first prove that no one is ever calling setLenght while the loop
> >> runs.[/color]
> >
> > As already discussed above, the specs don't force the compiler
> > to prove anything, do they?[/color]
>
> Yes, they do. Using volatile prevents the compiler from keeping the
> value in a register.[/color]

[snip]

Actually, the meaning of volatile is compiler-specific, but in general
it means that the compiler should not do any fancy optimizations to the
data at hand. That could mean not caching a variable in a register even
though the code doesn't appear to change it. By using volatile, the
programmer is indicating that the value could change due to something
outside the program (e.g. another thread or process or a hardware
device). See TC++PL A.7.1.

Cheers! --M

  #13  
Old January 13th, 2006, 10:55 AM
rodneys@gmx.de
Guest
 
Posts: n/a
Default Re: Memory access optimization

> Ok, this was a bad example. Change the line to j = 1; to show the[color=blue]
> problem with f(i).[/color]

Thank you! I have eventually understood why the optimization did
not happen.
The for-loop contains code like

for(int i=0;i<length;i++) {
data[i]= ...some floating point math...
}

As in your example, it is possible (at least from the compiler's point
of view) that the assignment to "data[i]" overwrites "length". One
would need a very potent data flow analysis to prove the opposite.
/*
Please insert here some C/C++ bashing.
Topic: Why does C/C++ constantly forces me to do things that
are done by the compiler in other language?
*/

Ramin

 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles