From: | mason@ease.com (Mark Mason) |
Newsgroups: | comp.compilers |
Date: | 29 Mar 1996 21:43:52 -0500 |
Organization: | none |
References: | 96-03-106 96-03-091 96-03-181 |
Keywords: | C, optimize, parallel |
Hello all,
>From cdg@nullstone.com (Christopher Glaeser):
> int f_()
> {
> static integer i;
>
> for (i = 1; i <= 100; ++i) { }
> return 0;
> }
Mark Hopkins <mark@omnifest.uwm.edu> wrote:
>Even if there were statements inside the {}, it should still optimize
>it by removing the "static", since having a static variable inside a
>procedure which is assigned to before its first use and after its
>declaration (and after any initializer) is exactly the same in effect
>as having an auto variable instead.
Although the above code is a bad example for the point I want to make,
the above statement is not entirely correct. Consider the case where
you have multiple threads of execution. Auto variables are placed
into registers or on the stack; their storage is associated with a
particular thread. Static locals are persistent (typically in the
data section) and shared between threads.
It is possible with a little work to write an (obviously contrived)
example which uses a static local variable to communicate between two
tasks. Having the compiler change the variable from static to auto
would definitely change the behavior of this program.
This will probably now lead to an interesting discussion of the
proper use of volatile in a multi-threaded environment. Most code
I've seen assumes that
1) shared data is in memory
2) synchronization primitives involve a function call
3) function calls possibly modify all memory.
So that in the following fragment, x need not be declared volatile:
/* sem_XXX() and spawn() and pseudo-ops */
void foo(int y)
{
static int x;
sem_take();
x = y;
sem_give();
/* sleep a random amount of time */
sem_take();
printf("x = %d\n", x);
sem_give();
}
void bar()
{
spawn(foo, 1);
spawn(foo, 2);
spawn(foo, 3);
}
The above is probably not strictly correct, but it is *very* common
not to have a volatile qualifier in a case like this.
The above example will break (change behavior) if either:
1) the compiler changes static locals to auto locals
2) the compiler can optimize memory accesses across
function calls (synchronization primitives). I'm
thinking mostly of CSE or constant-propagation here.
Mark Mason
_______________________________________________________________________________
Mark Mason EASE, Inc. 503-531-8909 (lab)
mason@ease.com 503-645-2696 (office) 503-690-7499 (fax)
[The C standard doesn't directly address parallel code, but it sure helps if
you understand what sequence points are. -John]
--
Return to the
comp.compilers page.
Search the
comp.compilers archives again.