Date: Sun, 27 Oct 2024 14:10:36 -0400
I think what you might be able to observe is not the cost of taking a lock
once unnecessarily, but the cost of performing an acquire load of the
atomic flag every time the function is entered, whereas the flag would be
non-atomic in Frederick's proposal. On some platforms (though, as I
understand it, not x86) the latter would be faster. But I suspect that it's
extremely rare for this difference to be significant in the context of the
entire application, except perhaps in some embedded applications (and
perhaps, on those platforms, there isn't support for multithreading in the
first place, so a `_SingleThreadOnly` annotation would be meaningless).
On Sun, Oct 27, 2024 at 2:02 PM Peter C++ via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> I wonder if the optimization of something happening once is actually
> measurable.
>
>
> sent from a mobile device so please excuse strange words due to
> autocorrection.
> Peter Sommerlad
> peter.cpp_at_[hidden]
> +41-79-432 23 32
>
> > On 27 Oct 2024, at 17:57, Frederick Virchanza Gotham via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >
> > Since C++11, we're guaranteed that a static variable defined inside a
> > function will be protected behind the scenes by an "std::once_flag" to
> > ensure that the variable only gets initialised once, and that
> > concurrent threads will wait for the initialising thread to finish.
> >
> > Sometimes we don't want this, for example if:
> > (1) The function will only ever be called by the same thread -- this
> > is very common in GUI programs (i.e. only the GUI thread calls the
> > function)
> > (2) You have your own locks inside the function
> >
> > C++ has always been about efficiency -- not paying for things that you
> > don't use. So how about we be able to opt out of the multi-threading
> > protection?
> >
> > Either mark the function, or mark the variable, something like:
> >
> > void MyFunction(void) _SingleThreadOnly
> > {
> > static SomeClass obj("monkey");
> > }
> >
> > or:
> >
> > void MyFunction(void)
> > {
> > static _SingleThreadOnly SomeClass obj("monkey");
> > }
> >
> > Sometimes we write a function in C++, expecting it to only have one
> > lock inside it (i.e. our own use of a 'mutex' or an 'atomic_flag'),
> > but then we check the assembler and we see that there are actually two
> > locks. We should be able to opt out of this unnecessary protection.
> >
> > Of course, this begs this question: What if the function is entered
> > concurrently by another thread while the object is being initialised?
> > One Possible Answer = "Undefined Behaviour".
> > --
> > Std-Proposals mailing list
> > Std-Proposals_at_[hidden]
> > https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
once unnecessarily, but the cost of performing an acquire load of the
atomic flag every time the function is entered, whereas the flag would be
non-atomic in Frederick's proposal. On some platforms (though, as I
understand it, not x86) the latter would be faster. But I suspect that it's
extremely rare for this difference to be significant in the context of the
entire application, except perhaps in some embedded applications (and
perhaps, on those platforms, there isn't support for multithreading in the
first place, so a `_SingleThreadOnly` annotation would be meaningless).
On Sun, Oct 27, 2024 at 2:02 PM Peter C++ via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> I wonder if the optimization of something happening once is actually
> measurable.
>
>
> sent from a mobile device so please excuse strange words due to
> autocorrection.
> Peter Sommerlad
> peter.cpp_at_[hidden]
> +41-79-432 23 32
>
> > On 27 Oct 2024, at 17:57, Frederick Virchanza Gotham via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >
> > Since C++11, we're guaranteed that a static variable defined inside a
> > function will be protected behind the scenes by an "std::once_flag" to
> > ensure that the variable only gets initialised once, and that
> > concurrent threads will wait for the initialising thread to finish.
> >
> > Sometimes we don't want this, for example if:
> > (1) The function will only ever be called by the same thread -- this
> > is very common in GUI programs (i.e. only the GUI thread calls the
> > function)
> > (2) You have your own locks inside the function
> >
> > C++ has always been about efficiency -- not paying for things that you
> > don't use. So how about we be able to opt out of the multi-threading
> > protection?
> >
> > Either mark the function, or mark the variable, something like:
> >
> > void MyFunction(void) _SingleThreadOnly
> > {
> > static SomeClass obj("monkey");
> > }
> >
> > or:
> >
> > void MyFunction(void)
> > {
> > static _SingleThreadOnly SomeClass obj("monkey");
> > }
> >
> > Sometimes we write a function in C++, expecting it to only have one
> > lock inside it (i.e. our own use of a 'mutex' or an 'atomic_flag'),
> > but then we check the assembler and we see that there are actually two
> > locks. We should be able to opt out of this unnecessary protection.
> >
> > Of course, this begs this question: What if the function is entered
> > concurrently by another thread while the object is being initialised?
> > One Possible Answer = "Undefined Behaviour".
> > --
> > Std-Proposals mailing list
> > Std-Proposals_at_[hidden]
> > https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
-- *Brian Bi*
Received on 2024-10-27 18:10:51