- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would like to modify the value of the object inside operator method look like this:
but because the operator method must be declared const keyword, so I cannot modify the value. What should I do?
[cpp]class Case { int sampleVar; public: void operator() (const blocked_range& range) const { for(int i = range.begin(), i != range.end(), i++) { // do some tasks sampleVar++; } } Case(int sampleVar): sampleVar(sampleVar) {} };[/cpp]
but because the operator method must be declared const keyword, so I cannot modify the value. What should I do?
Link Copied
12 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
mutable int sampleVar;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Raf Schietekat
mutable int sampleVar;
AFAIR, functor can be executing and concurrently coping. If so, mutable is not the way. If only single variable of primitive type is copied, then mutable tbb::atomic
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't know, I didn't feel like speculating about the context at this time, but I don't think I would try copying atomics myself, concurrently or otherwise.
Meanwhile, there's this pipeline thing that I don't care to look at again for at least a month, so maybe you could shine your light on that, too?
Meanwhile, there's this pipeline thing that I don't care to look at again for at least a month, so maybe you could shine your light on that, too?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Raf Schietekat
I don't know, I didn't feel like speculating about the context at this time, but I don't think I would try copying atomics myself, concurrently or otherwise.
What do you mean?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Raf Schietekat
Meanwhile, there's this pipeline thing that I don't care to look at again for at least a month, so maybe you could shine your light on that, too?
There is so many unconnected questions/answers/discussions, what exactly moment do you mean?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"What do you mean?" Maybe I should have another look at it (and explain the fifth line), but I wrote these comments in my "Additions to atomic" proposal:
// About copy constructors and copy assignment operators:
// Normally these must be defined together for consistency.
// Atomics cannot have copy constructors because that would also require the definition of a default constructor,
// which would interfere with the expectation that atomics are ready for use right after static initialization;
// any use of a(n implicitly defined) copy constructor should be avoided, however.
// They must have copy assignment operators to invoke store(), because, unlike the situation with constructors,
// a copy assignment operator will be implicitly defined even if another user-defined assignment operator exists,
// and selectively restricting assignment would only invite accidental use of a (non-atomic) implicit definition.
// TODO: double check the last statement
On a related topic, I also wrote this (reformatted):
// default-initialization does not translate to zero-initialization because atomic is non-POD
// because it has a copy assignment operator, which means that putting my_atomic()
// in an initializer list or doing "tbb::atomic a; a = tbb::atomic();"
// is incorrect (it doesn't do what it seems to be expected to do).
What do you think?
"There is so many unconnected questions/answers/discussions, what exactly moment do you mean?"
See "Pipeline" thread: I published a code snapshot, but it doesn't work yet, and I need to take a break from it myself to regain a fresh perspective.
// About copy constructors and copy assignment operators:
// Normally these must be defined together for consistency.
// Atomics cannot have copy constructors because that would also require the definition of a default constructor,
// which would interfere with the expectation that atomics are ready for use right after static initialization;
// any use of a(n implicitly defined) copy constructor should be avoided, however.
// They must have copy assignment operators to invoke store(), because, unlike the situation with constructors,
// a copy assignment operator will be implicitly defined even if another user-defined assignment operator exists,
// and selectively restricting assignment would only invite accidental use of a (non-atomic) implicit definition.
// TODO: double check the last statement
On a related topic, I also wrote this (reformatted):
// default-initialization does not translate to zero-initialization because atomic is non-POD
// because it has a copy assignment operator, which means that putting my_atomic()
// in an initializer list or doing "tbb::atomic
// is incorrect (it doesn't do what it seems to be expected to do).
What do you think?
"There is so many unconnected questions/answers/discussions, what exactly moment do you mean?"
See "Pipeline" thread: I published a code snapshot, but it doesn't work yet, and I need to take a break from it myself to regain a fresh perspective.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Raf Schietekat
"What do you mean?" Maybe I should have another look at it (and explain the fifth line), but I wrote these comments in my "Additions to atomic" proposal:
// About copy constructors and copy assignment operators:
// Normally these must be defined together for consistency.
// Atomics cannot have copy constructors because that would also require the definition of a default constructor,
// which would interfere with the expectation that atomics are ready for use right after static initialization;
// any use of a(n implicitly defined) copy constructor should be avoided, however.
// They must have copy assignment operators to invoke store(), because, unlike the situation with constructors,
// a copy assignment operator will be implicitly defined even if another user-defined assignment operator exists,
// and selectively restricting assignment would only invite accidental use of a (non-atomic) implicit definition.
// TODO: double check the last statement
On a related topic, I also wrote this (reformatted):
// default-initialization does not translate to zero-initialization because atomic is non-POD
// because it has a copy assignment operator, which means that putting my_atomic()
// in an initializer list or doing "tbb::atomic a; a = tbb::atomic();"
// is incorrect (it doesn't do what it seems to be expected to do).
What do you think?
// About copy constructors and copy assignment operators:
// Normally these must be defined together for consistency.
// Atomics cannot have copy constructors because that would also require the definition of a default constructor,
// which would interfere with the expectation that atomics are ready for use right after static initialization;
// any use of a(n implicitly defined) copy constructor should be avoided, however.
// They must have copy assignment operators to invoke store(), because, unlike the situation with constructors,
// a copy assignment operator will be implicitly defined even if another user-defined assignment operator exists,
// and selectively restricting assignment would only invite accidental use of a (non-atomic) implicit definition.
// TODO: double check the last statement
On a related topic, I also wrote this (reformatted):
// default-initialization does not translate to zero-initialization because atomic is non-POD
// because it has a copy assignment operator, which means that putting my_atomic()
// in an initializer list or doing "tbb::atomic
// is incorrect (it doesn't do what it seems to be expected to do).
What do you think?
I think that functor's copy ctor must be defined explicitly:
struct functor
{
tbb::atomic
...
functor(functor const& f)
{
x.store(f.x.load(relaxed), relaxed);
}
};
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Raf Schietekat
"There is so many unconnected questions/answers/discussions, what exactly moment do you mean?"
See "Pipeline" thread: I published a code snapshot, but it doesn't work yet, and I need to take a break from it myself to regain a fresh perspective.
See "Pipeline" thread: I published a code snapshot, but it doesn't work yet, and I need to take a break from it myself to regain a fresh perspective.
I see the attachment in the last post, and I have skimmed over the thread, but I don't get what problem the attachment tries to solve, or what it tries to improve. What it's all about?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"I think that functor's copy ctor must be defined explicitly" Maybe, but I just didn't want to speculate on what's going on here (I did think about suggesting "tbb::atomic
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Dmitriy Vyukov
I see the attachment in the last post, and I have skimmed over the thread, but I don't get what problem the attachment tries to solve, or what it tries to improve. What it's all about?
Over to "Pipeline"...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, the functor body might be copied by the implementation of parallel_for. The simplest solution is pass sampleVar by reference and make sampleVar atomic, as shown below:
[cpp]class Case { atomic& sampleVar; public: void operator() (const blocked_range & range) const { for(int i = range.begin(), i != range.end(), i++) { // do some tasks sampleVar++; } } Case(atomic & sampleVar_): sampleVar(sampleVar_) {} }; [/cpp]
[cpp][/cpp]
Another option, which works if sampleVar is not being read until the parallel loop completes, is to use parallel_reduce. Using paralle_reduce this way may improve performance, because it allows you to accumulate in local copies of sampleVar and then sum them. Look at file examples/parallel_reduce/primes/primes.cpp in the TBB ditribution. Inside there is a class Sieve that tallies a counter variable "count". You can tally sampleVar in a similar way. Be sure to inspect how method Sieve(Sieve&&,split) initializes a local count and method Sieve::join sums two local counts.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Arch Robison (Intel)
Another option, which works if sampleVar is not being read until the parallel loop completes, is to use parallel_reduce.
A side note: this reminded me of a suggestion I have heard earlier, which was for TBB algorithms, parallel_reduce in particular,to return a copy of the body object. This object can then be assigned to some variable, and it might have a conversion operator so that the following could be written:
int my_sum = parallel_reduce(blocked_range

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page