Problem compiling parallel_for with mutable lambda
-
2010年8月25日 下午 02:22
I'm having trouble getting clean compilationm of a simple example of a parallel_for with a lambda that wants a couple of mutable copies of stack variables.
When I compile code with the snippet below, where everything is captured as reference there are no issues:
...
struct dvinfo
{
double dv;
double index;
};
Concurrency::combinable<std::vector<dvinfo>> localdv;
Concurrency::parallel_for (size_t(0), size_t(nl), [&/*,dv5,k*/](size_t i) /*mutable*/ {
dv5=perturb6((int)y[i],ndest[i],nhard,a,b,lhs,lhs1,loc[i],type,v0);
if (dv5<0.0)
{
localdv.local()[k].dv=dv5;
localdv.local()[k++].index=i;
}
});
...it compiles fine, but if I want to create mutable copies of a couple of the stack variables by removing the comment brackets:
...
struct dvinfo
{
double dv;
double index;
};
Concurrency::combinable<std::vector<dvinfo>> localdv;
Concurrency::parallel_for (size_t(0), size_t(nl), [&,dv5,k](size_t i) mutable {
dv5=perturb6((int)y[i],ndest[i],nhard,a,b,lhs,lhs1,loc[i],type,v0);
if (dv5<0.0)
{
localdv.local()[k].dv=dv5;
localdv.local()[k++].index=i;
}
});
...I get the error:
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\ppl.h(1955): error C3848: expression having type 'const `anonymous-namespace'::<lambda0>' would lose some const-volatile qualifiers in order to call 'void `anonymous-namespace'::<lambda0>::operator ()(size_t)'
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\ppl.h(2021) : see reference to function template instantiation 'void Concurrency::_Parallel_for_impl<_Index_type,_Function>(_Index_type,_Index_type,_Index_type,const _Function &)' being compiled
1> with
1> [
1> _Index_type=size_t,
1> _Function=`anonymous-namespace'::<lambda0>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\ppl.h(2052) : see reference to function template instantiation 'void Concurrency::parallel_for<_Index_type,_Function>(_Index_type,_Index_type,_Index_type,const _Function &)' being compiled
1> with
1> [
1> _Index_type=size_t,
1> _Function=`anonymous-namespace'::<lambda0>
1> ]
1> pgm.cpp(1040) : see reference to function template instantiation 'void Concurrency::parallel_for<size_t,`anonymous-namespace'::<lambda0>>(_Index_type,_Index_type,const _Function &)' being compiled
1> with
1> [
1> _Index_type=size_t,
1> _Function=`anonymous-namespace'::<lambda0>
1> ]What secret incantation am I missing?
Roger
所有回覆
-
2010年8月25日 下午 09:22
The algorithms are not intended to be utilized with mutable functors. There are a variety of places in the PPL where the functor may get copied. When the copy's function call operator is made, it may get made on this copy resulting in mutation of the copy and not the original. For consistency across the API set, all of the algorithms take const references to the functors. If you truly need mutation of something outside, an explicit by-ref capture is required. Mutation of a private copy can be done explicitly with a private copy.
Even if the PPL were to allow mutation in places, your example above would have multiple threads pounding on the mutable fields of the lambda with no synchronization (e.g.: the single instance of dv5 would get overwritten by all threads within the parallel for).
- 已提議為解答 Dana Groff 2010年8月31日 上午 01:52
- 已標示為解答 Dana Groff 2010年9月8日 下午 05:35

