The use case I'm imagining, is to use static to only construct
regex's, or other constant datastructures once:
bool string_matches_pattern (std::string str) {
static const std::regex my_regex(R"(some_regex_pattern)");
return regex_match(str, my_regex);
}
For this to be thread safe, the language would have to implicitly
generate a mutex and lock it around initialization of static locals. I
know there was some work done on the C++0x memory model, and getting
the language ready for thread safety, and I was wondering if this was
ever done?
Alternatively, is it possible to mark local variables, thread_local in
C++0x?
bool string_matches_pattern (std::string str) {
thread_local const std::regex my_regex(R"(some_regex_pattern)");
return regex_match(str, my_regex);
}
This would construct the regex once for every thread.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Yes, there has been added extra wording that provides special guarantees
in 6.7 [stmt.dcl] p. 4:
"If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.(88)"
with footnote 88:
"The implementation must not introduce any deadlock around execution of the initializer."
> Alternatively, is it possible to mark local variables, thread_local in
> C++0x?
>
> bool string_matches_pattern (std::string str) {
> thread_local const std::regex my_regex(R"(some_regex_pattern)");
> return regex_match(str, my_regex);
> }
>
> This would construct the regex once for every thread.
Yes, this is also possible.
HTH & Greetings from Bremen,
Daniel Krügler
That statement is neither true nor false. The current C++ standard
makes no mention of threads whatsoever. Many C++ compilers do support
threads, and you'd need to read their documentation (and possibly
experiment if the documentation isn't clear) to see whether
initialisation of variables with static storage (whether at namespace
scope or at block scope) is thread safe. My impression is that
compilers have been gradually moving towards thread-safe
initialisation.
> I was wondering whether this was addressed at all in C++0x?
Yes, 6.7, paragraph 4, says while talking about the initialisation of
block-scope variables with static storage duration: "If control enters
the declaration concurrently while the variable is being initialized,
the concurrent execution shall wait for completion of the
initialization." I think that's the guarantee you're looking for.
> The use case I'm imagining, is to use static to only construct
> regex's, or other constant datastructures once:
>
> bool string_matches_pattern (std::string str) {
> static const std::regex my_regex(R"(some_regex_pattern)");
> return regex_match(str, my_regex);
> }
That's already a fairly standard idiom in single-threaded code, or
where the compiler already makes a suitable guarantee about thread-
safe static initialisation. I expect it will continue to be.
That said, it's not clear this is always a good idea. In single-
threaded code, the cost of accessing a static variable is only
marginally higher than an automatic variable (i.e. one on the stack):
that comes from the double indirection often required to access the
variable and potential for cache misses due to the non-locality of the
static object. But in heavily threaded code, it can be much worse,
with the implementation having to perform some sort of locking (e.g.
with a mutex) around each function call. With lots of threads, that
can result in significant contention if the code is called frequently.
There's a danger that this sort of code is a premature optimisation.
Have you profiled the constructor of std::regex with the sort of
regexs it is likely to be given? Have you profiled the cost of
locking around a static variable when run with the number of active
threads you're likely to have? Which is actually faster? And is the
code on a critical enough path for you to care?
> For this to be thread safe, the language would have to implicitly
> generate a mutex and lock it around initialization of static locals. I
> know there was some work done on the C++0x memory model, and getting
> the language ready for thread safety, and I was wondering if this was
> ever done?
Yes. C++0x knows about threads, provides a memory model that makes
some guarantees about what they can and cannot do, and also includes a
nice threading library (that I, for one, find cleaner to use than any
of the others I've tried).
> Alternatively, is it possible to mark local variables, thread_local in
> C++0x?
>
> bool string_matches_pattern (std::string str) {
> thread_local const std::regex my_regex(R"(some_regex_pattern)");
> return regex_match(str, my_regex);
> }
Yes, that's legal in C++0x. (You can optionally write it as
"thread_local static" or "static thread_local" if you feel that makes
it clearer. I tend towards preferring the latter, but they're all
synonymous.)
I haven't looked into the costs involved in initialising a thread-
local static variable. As above, if the reason you want to avoid
constructing it once per function call is efficiency, I suggest you
actually do some measurements to check that what you're doing does
actually yield an improvement. (And if you do, perhaps you might like
to post back what you discover so we can all learn from it?)
Richard Smith
> In C++ static local initialization was not thread safe. I was
> wondering whether this was addressed at all in C++0x?
Yes, proper synchronization is required.
> Alternatively, is it possible to mark local variables, thread_local in
> C++0x?
Yes, thread-local variables are supported.
--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The Standard C++ Library Extensions: a Tutorial and Reference (www.petebecker.com/tr1book)
Daniel Krügler wrote:
[...]
> "If control enters the declaration concurrently while the variable
> is being initialized, the concurrent execution shall wait for
> completion of the initialization.[footnote]"
The above is defective in the sense that it doesn't allow to mark the
declaration (in)feasible for concurrent control entering and hence
requires all static locals to pay the overhead even if it is not needed
for a particular static local: that's not good.
regards,
alexander.
AFAIK, the second argument was considered as weak, because a suggested
implementation technique as outlined in
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2513.html
and it's predecessors seemed to indicate that this potential overhead
should be insignificant.
Since you seem to disagree with this interpretation, do you have a
specific use-case where the current requirements would be rather
ill-advised and would prevent writing high-performance programs?
Thanks & Greetings from Bremen,
Daniel Krügler
Daniel Krügler wrote:
[...]
> AFAIK, the second argument was considered as weak, because a suggested
> implementation technique as outlined in
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2513.html
The idea to use thread locals to ensure thread safety of static locals
predates that 2008 paper (and its predecessors in 2007), see e.g.
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
(Fixing Double-Checked Locking using Thread Local Storage)
http://groups.google.com/group/comp.lang.c++.moderated/msg/b89ed310a0569bc1
(Subject: Re: Multithreading theory)
>
> and it's predecessors seemed to indicate that this potential overhead
> should be insignificant.
>
> Since you seem to disagree with this interpretation, do you have a
> specific use-case where the current requirements would be rather
> ill-advised and would prevent writing high-performance programs?
The overhead of thread locals is still the overhead which is not free.
regards,
alexander.