Date: Fri, 10 Jan 2020 18:15:42 +0100
I thought the whole point of this TM-light approach
was to forego (specified) compile-time checking in
favor of broad undefined behavior, so that we can
entice more implementers to actually implement TM.
Of course, implementers are always encouraged to
diagnose / warn about dubious code, but that's a
service to their users, beyond the call of duty
(= what the standard specifies).
> But a programmer should also be able to say "I need the compiler to
> guarantee that this is going to be defined behavior, so that I don't
> have a debugging nightmare later".
That requires quite a bit of specification work, because
the extent and scope of the compiler guarantee needs to be
clearly defined. And people disliked the function annotations
from the earlier TM TS.
So, do you want to restrict the scope of the compiler guarantee
to stuff you lexically wrote inside the atomic block? That's
conceivable, but doesn't cover the "dynamic extent" view.
Jens
On 10/01/2020 16.04, Michael Spear via SG5 wrote:
> It seems we need two things:
> 1 - A broad definition of what is defined behavior. Michael seems to be working towards this.
> 2 - A definition of a statically checkable defined behavior. Hans seems to be working towards this.
>
> A programmer should be able to say "I know this is defined behavior, even if the compiler doesn't, so I'm willing to turn off some check (or not turn on some check) because my HTM is going to do the right thing". But a programmer should also be able to say "I need the compiler to guarantee that this is going to be defined behavior, so that I don't have a debugging nightmare later". In the latter case, overly rigid rules are ok... if they become too annoying, and the use case is too important, then we know it's time to upgrade the specification.
>
> - Mike
>
> On Fri, Jan 10, 2020 at 9:46 AM Michael L. Scott via SG5 <sg5_at_[hidden] <mailto:sg5_at_[hidden]>> wrote:
>
> On Jan 9, 2020, at 6:24 PM, Hans Boehm <boehm_at_[hidden] <mailto:boehm_at_[hidden]>> wrote:
>
> > As was pointed out in the meeting there seem to be two reasons to restrict calls to other translation units, probably by relying on constexpr, neither 100% convincing:
> >
> > 1) To accommodate STM or hybrid TM. I agree that there is no correctness issue with supporting such calls. But in the past, we had significant concerns about usability of such a system. You can't really tell whether you're getting an even minimally scalable implementation of a simple standard library call without knowing whether its implementation resides in the same TU, which is now not easily determinable, and may change with the next release.
>
> But in an implementation based on HTM and a fall-back lock (the principal target for TM-lite, I think), there is already no way to be sure whether an algorithm will scale -- e.g., whether its transaction write sets exceed hardware buffering capacity.
>
> > 2) It makes it easier for an implementation to report when a data-race-free atomic{} block isn't really atomic because it internally uses e.g. locks, and can thus communicate with other threads before the (now irrevocable) transaction commits. Without the restriction, this would presumably require dynamic tests associated with locks and atomics. With it, the checks could be restricted to TUs containing atomic blocks, e.g. by cloning code called from within transactions.
>
> But there’s already no way to tell at compile time whether a transaction will acquire a lock at run time. Dynamic checks will always be required if we want to catch all uses of locks in transactions. (Personally, I’m fine with undefined behavior.)
>
> > Another weak argument is that since you can know you are within a transaction, you could presumably generate more HTM-friendly code in some cases. I don't know whether that's an issue with any existing hardware. Are there useful compiler-generated instructions that always fail in some HTM implementation?
>
> Why is this an argument for a very small set of required-to-be-supported operations? One could always generate HTM-friendly code in the cases where it’s possible. I don’t see the argument for allowing an implementation to forbid external calls in the interest of enabling optimizations, unless we can come up with a case where allowing external calls would preclude optimizing transactions that don’t make such calls.
>
> > I agree that using constexpr is imperfect. And there are cases in which the library vendor will need to change their code to adapt. I think we're only proposing using constexpr for the standard library; for other libraries the theory is that the user can tell what's defined in the same translation unit.
>
> - Michael
> --
> SG5 mailing list
> SG5_at_[hidden] <mailto:SG5_at_[hidden]>
> https://lists.isocpp.org/mailman/listinfo.cgi/sg5
>
>
was to forego (specified) compile-time checking in
favor of broad undefined behavior, so that we can
entice more implementers to actually implement TM.
Of course, implementers are always encouraged to
diagnose / warn about dubious code, but that's a
service to their users, beyond the call of duty
(= what the standard specifies).
> But a programmer should also be able to say "I need the compiler to
> guarantee that this is going to be defined behavior, so that I don't
> have a debugging nightmare later".
That requires quite a bit of specification work, because
the extent and scope of the compiler guarantee needs to be
clearly defined. And people disliked the function annotations
from the earlier TM TS.
So, do you want to restrict the scope of the compiler guarantee
to stuff you lexically wrote inside the atomic block? That's
conceivable, but doesn't cover the "dynamic extent" view.
Jens
On 10/01/2020 16.04, Michael Spear via SG5 wrote:
> It seems we need two things:
> 1 - A broad definition of what is defined behavior. Michael seems to be working towards this.
> 2 - A definition of a statically checkable defined behavior. Hans seems to be working towards this.
>
> A programmer should be able to say "I know this is defined behavior, even if the compiler doesn't, so I'm willing to turn off some check (or not turn on some check) because my HTM is going to do the right thing". But a programmer should also be able to say "I need the compiler to guarantee that this is going to be defined behavior, so that I don't have a debugging nightmare later". In the latter case, overly rigid rules are ok... if they become too annoying, and the use case is too important, then we know it's time to upgrade the specification.
>
> - Mike
>
> On Fri, Jan 10, 2020 at 9:46 AM Michael L. Scott via SG5 <sg5_at_[hidden] <mailto:sg5_at_[hidden]>> wrote:
>
> On Jan 9, 2020, at 6:24 PM, Hans Boehm <boehm_at_[hidden] <mailto:boehm_at_[hidden]>> wrote:
>
> > As was pointed out in the meeting there seem to be two reasons to restrict calls to other translation units, probably by relying on constexpr, neither 100% convincing:
> >
> > 1) To accommodate STM or hybrid TM. I agree that there is no correctness issue with supporting such calls. But in the past, we had significant concerns about usability of such a system. You can't really tell whether you're getting an even minimally scalable implementation of a simple standard library call without knowing whether its implementation resides in the same TU, which is now not easily determinable, and may change with the next release.
>
> But in an implementation based on HTM and a fall-back lock (the principal target for TM-lite, I think), there is already no way to be sure whether an algorithm will scale -- e.g., whether its transaction write sets exceed hardware buffering capacity.
>
> > 2) It makes it easier for an implementation to report when a data-race-free atomic{} block isn't really atomic because it internally uses e.g. locks, and can thus communicate with other threads before the (now irrevocable) transaction commits. Without the restriction, this would presumably require dynamic tests associated with locks and atomics. With it, the checks could be restricted to TUs containing atomic blocks, e.g. by cloning code called from within transactions.
>
> But there’s already no way to tell at compile time whether a transaction will acquire a lock at run time. Dynamic checks will always be required if we want to catch all uses of locks in transactions. (Personally, I’m fine with undefined behavior.)
>
> > Another weak argument is that since you can know you are within a transaction, you could presumably generate more HTM-friendly code in some cases. I don't know whether that's an issue with any existing hardware. Are there useful compiler-generated instructions that always fail in some HTM implementation?
>
> Why is this an argument for a very small set of required-to-be-supported operations? One could always generate HTM-friendly code in the cases where it’s possible. I don’t see the argument for allowing an implementation to forbid external calls in the interest of enabling optimizations, unless we can come up with a case where allowing external calls would preclude optimizing transactions that don’t make such calls.
>
> > I agree that using constexpr is imperfect. And there are cases in which the library vendor will need to change their code to adapt. I think we're only proposing using constexpr for the standard library; for other libraries the theory is that the user can tell what's defined in the same translation unit.
>
> - Michael
> --
> SG5 mailing list
> SG5_at_[hidden] <mailto:SG5_at_[hidden]>
> https://lists.isocpp.org/mailman/listinfo.cgi/sg5
>
>
Received on 2020-01-10 11:18:20