Re: [sv-ec] fork..join_none/join_any and automatic variables


Subject: Re: [sv-ec] fork..join_none/join_any and automatic variables
From: Randy Misustin (ram@model.com)
Date: Thu May 22 2003 - 08:58:58 PDT


  Hi Steve,

More below...

Steven Sharp wrote:

>>>This is relevant to fork-join used inside an automatic task or function
>>>in 1364-2001. That behavior is well defined. If SV comes up with a
>>>different answer, then it is incompatible.
>>>
>>>
>>>
>>>
>>What do you mean by "well defined"? I couldn't find anything that
>>directly addressed the topic of the effect of a fork on automatic
>>variables defined in an enclosing scope. Perhaps you know of a place
>>this is addressed? Or perhaps you're inferring that a lack of discussion
>>of this topic is tantamount to defining that this behavior should be the
>>same as with static variables?
>>
>>
>
>Unfortunately, what I mean isn't the same thing as "well documented."
>I mean that the conceptual model of automatic scopes in 1364-2001 is
>not the kind of vague, open-to-interpretation thing that has been
>implied by some of this email. The conceptual model is precise and
>complete, and I and some others who worked on 1364-2001 have a full
>understanding of it, even if the description in the standard may not
>be as clear as it could be.
>
>
Oh boy. I can debate and discuss technical merits. I can also endeavor
to interpret the 1364-2001 spec and have a reasonable discussion about
what might have been meant or mightn't. I'll wager, though, that if I
engage you on this precise and complete conceptual model you're
claining, I'm going to have a wee bit of difficulty. I don't suppose
you'd consider substituting my conceptual model for yours in this
debate, would you?

>There is no discussion of the effect of fork on automatic variables in
>an enclosing scope, because it has no effect. It is no more relevant
>than a discussion of the effect of if-then-else or a repeat-loop on
>automatic variables in an enclosing scope. I would never claim that
>the LRM is complete, but in this case the lack of discussion is because
>there is no special behavior. The LRM cannot specify the individual
>interactions between all features, but must rely on a general assumption
>that they are orthogonal unless specified otherwise.
>
>
I must say that, for me, there is a huge difference between
loops/conditionals and forks. The lack of treatment in the spec led me
to believe that forks were simply not considered in the discussions of
this feature. If you and other committee members are comfortable that
you understand the issues and it's correctly resolved, I'm also
comfortable and will get on with my job. Of course, this interpretation
does still present difficulty in finding reasonable (conceptual and
efficient) semantics for the fork-join_none!

>Note that Jamie already directed a question about this to the IEEE
>1364 Errata Task Force. You can see the response at:
>
>http://www.boyd.com/1364_btf/report/full_pr/281.html
>
>
I must confess to being aware of this already. I've opened the
discussion here after recognizing the larger issue of fok-join_none.

>>>A subprocess created inside the scope will not.
>>>
>>>
>>>
>>Why not? (Oops, never mind. I guess that's what we're debating ;^).
>>
>>
>
>First of all, because the LRM text does not specify that it is. Second,
>because the conceptual model that the LRM text is based on says that it
>isn't (and we have the IEEE ETF ruling on that). And third, because it
>wouldn't be desirable.
>
>We aren't talking about another unrelated process coming into the scope
>and getting its own variables for that scope. We are talking about the
>existing process breaking itself into subprocesses that continue executing
>from the split point as extensions of the parent. Even in the incorrect
>interpretation, you are automatically assuming that the newly allocated
>variables will start out inheriting an initial value from the parent
>variable (acknowledging that you want them to have the same value).
>Or perhaps the term "copy" led you into thinking this.
>
>This is not the case; automatic variables are always initialized to their
>default value (X for non-reals) when allocated. This should tell you that
>there is a mismatch between your conceptual model and the one that 1364-2001
>is based on.
>
>It should also tell you that it won't work the way you seem to want. Since
>newly allocated automatic variables always start out X, allocating new ones
>for each subprocess would cut the subprocess off from the automatic variables
>in its surrounding scopes and make it work in isolation. This is not
>desirable. You want to maintain access to the surrounding environment. If
>you need some newly allocated and initialized automatic variables in the
>subprocess, you can already get those by declaring them in the subprocess.
>
>
I don't particularly want any predetermined outcome. I agree with much
of the facts you present here, although many of your
opinions/conclusions are somewhat over-the-top.

>Yes, you can make up a different scheme, such as allocating new variables
>for each subprocess, initialized to the value in the parent, but it would
>not be consistent with 1364-2001. It would be unnecessarily inefficient
>also. Nor would it match the scoping rules of Verilog or any other
>language I know.
>
>
Scoping rules? What do scoping rules have to do with this?

>>>The new types of nonblocking forks would fall under the description in
>>>10.2.3 of 1364-2001 that says "Because variables declared in automatic
>>>tasks are deallocated at the end of the task invocation, they shall not
>>>be used in certain constructs that might refer to them after that point."
>>>Since a subprocess of such a fork might refer to the variable after it
>>>had been deallocated, such a subprocess would not be allowed to reference
>>>the automatic variable. Of course these forks are not listed in the
>>>specific examples in 1364-2001 since they are not part of the language,
>>>but they are in the same category as those examples.
>>>
>>>These forks do create a new wrinkle. The subprocesses in 1364-2001
>>>cannot themselves introduce new scopes and automatic variables, while
>>>the new fork types can. A subprocess of a fork-join_any could contain
>>>a begin-end block that declares some automatic variables. There is no
>>>reason why this would not be legal and why the subprocess could not
>>>refer to these variables. The subprocess cannot out-survive the variables
>>>in this situation. The restriction would become more complex: instead of
>>>not being allowed to refer to any automatic variables, the subprocesses
>>>would not be allowed to refer to any automatic variable in a scope outside
>>>the subprocess. Note that such automatic variables declared inside of a
>>>fork-join_any subprocess would be allocated each time execution entered
>>>their scope, so that if the subprocess were executed multiple times
>>>concurrently, each subprocess would have its own copies.
>>>
>>>
>>>
>>>
>>Go Steve! I presume you mean "join_none" in the above (I misspoke the
>>same thing in my original post, so this is undoubtably my fault).
>>
>>
>
>Doesn't join_any allow the parent process to continue as soon as any
>child completes, leaving the other children running? If not, then my
>mistake. If so, then it has the same problem as join_none of leaving
>child subprocesses that could outlive the parent process, which will
>be allocating and deallocating its automatic variables. At any rate,
>join_none has this problem, whether join_any does or not.
>
>
I hadn't thought so, but on double checking I do believe you're correct.

>The general solution in 1364-2001 for types of subprocesses that could
>outlive automatic variables in the scope around them is to disallow such
>subprocesses from accessing automatic variables. Since most of these
>subprocesses are things you wouldn't tend to use in a reentrant task or
>function anyway, this doesn't create any hardship. This rule could be
>extended to cover these new fork subprocesses, but this is admittedly
>more likely to be inconvenient.
>
>
I agree that applying 1364-2001 precedents would simply disallow
accesses to such variables. I'm not sure that's desirable.

>>Additionally, I seem to have this strong desire to define automatic
>>tasks and functions in terms of a traditional execution stack model.
>>This is a proven high-performance path to achieving reentrancy. The
>>largest obstacle (that I've so far considered) to this is this fork-join
>>strangeness. I'd hate for a lack of thoughful consideration of the
>>ramifications of this to be the blocking issue to a nice implementation.
>>Of course, this desire in me is probably curable.
>>
>>
>
>Verilog designs generally involve such a large number of separate
>threads of execution that traditional mechanisms are impractical.
>High performance requires using a mechanism that handles that well
>first, and then fitting reentrant calls into it.
>
>At any rate, I don't understand what a traditional execution stack model
>has to do with what you are suggesting. Traditional programming languages
>do not make new copies of the variables in a stack frame when entering a
>nested scope or calling another subroutine. When they allow access to the
>caller's variables from a subroutine, they use a link to the original
>stack frame containing the variables, rather than making a copy.
>
>Nor does making a copy of the parent's stack frame for each of the child
>processes so they can continue to access their copy after the original
>is deallocated (if that is what you are suggesting) sound like a
>high-performance path to anything. It may be desirable to provide some
>mechanism for passing selected values that were in automatic variables
>in the parent process into automatic variables in the child process, but
>I don't think this is the way to do it. It is inefficient and inconsistent.
>
>
Ach, you misunderstand! My concern for performance and synergy with
processor architecture doesn't have anything to do with the handling of
the fork; it has to do with the the handling of automatic variables. My
feeling is that automatic variables would most efficiently be allocated
within a conventional stack frame rather than dynamically outside the
stack frame. Your interpretation of the proper interaction with the fork
construct is making this strategy difficult.

>>I can't tell where your last paragraph is leading. Are you suggesting,
>>similar to Dave Rich, that fork-join_none ought to treat outer-scoped
>>automatic variables differently than other forms of fork or are you
>>starting to argue for the removal of fork-join_none?
>>
>>
>
>I acknowledged that fork-join_none (and possibly fork-join_any) have a
>problem that does not occur for fork-join. I pointed out that this could
>be prevented by interpreting a rule in 1364-2001 to apply to these
>subprocesses as well, which would prevent them from accessing automatic
>variables and having this problem. Applying the spirit rather than the
>letter of the rule would still allow them to declare and use automatic
>variables in scopes local to the subprocess. However, this still provides
>no mechanism by which they can access the values of automatic variables in
>scopes around them, even to copy them into their own local automatic variables
>when they are first forked off. I think this would be desirable, but I
>don't see a simple way of adding this in the existing proposal without a
>major kludge of some kind.
>
>Aside from applying this restriction from 1364-2001 only to the problematic
>forms of fork, I haven't suggested making the different forms of fork behave
>differently. I think they should work as similarly as possible.
>
>
Thanks for clarifying your position.

-randy.

>Steven Sharp
>sharp@cadence.com
>
>



This archive was generated by hypermail 2b28 : Thu May 22 2003 - 09:25:52 PDT