Pregunta

I have been getting this error come up in the for loop when I try to assign values to x_dev, y_dev, and pearson. As far as I can see they should all be modifiable. Can anyone see where I have gone wrong?

class LoopBody
{  
    double *const x_data;
    double *const y_data;
    double const x_mean;
    double const y_mean;  
    double x_dev;
    double y_dev;
    double pearson; 


public:
    LoopBody(double *x, double *y, double xmean, double ymean, double xdev, double ydev, double pear) 
            : x_data(x), y_data(y), x_mean(xmean), y_mean(ymean), x_dev(xdev), y_dev(ydev), pearson(pear) {}  

    void operator() (const blocked_range<size_t> &r) const {              
        for(size_t i = r.begin(); i != r.end(); i++)
        {
            double x_temp = x_data[i] - x_mean;
            double y_temp = y_data[i] - y_mean;

            x_dev += x_temp * x_temp;
            y_dev += y_temp * y_temp;

            pearson += x_temp * y_temp;

        }
    }
};

Having followed @Bathsheba 's advice I have overcome these problems. However When running a parallel_for the operator is runs but the for loop is never entered.

This is where I call the parallel_for:

parallel_for(blocked_range<size_t>(0,n), LoopBody(x, y, x_mean, y_mean, x_dev, y_dev, pearson), auto_partitioner());
¿Fue útil?

Solución

The () operator is marked const, and you're attempting to modify class member data (e.g. x_dev, y_dev and person). That is not allowed and is why you're getting the compile-time error.

You probably want to drop the const from the method.

Alternatively you can mark the member data that you want to modify as mutable, but this is not the preferred solution as it makes code brittle, difficult to read and can wreak havoc with multi-threading.

Otros consejos

Seemingly you want to do reduction, i.e. compute some aggregate values over the data.

For that, TBB offers a special function template: parallel_reduce. Unlike parallel_for that perhaps you use now, parallel_reduce does not require operator() of a body class to be const, because an instance of that class accumulates partial results. However, it poses other requirements to the class: the need to have a special constructor as well as a method to merge partial results from another body instance.

More information can be found in the Intel(R) TBB User Guide: http://www.threadingbuildingblocks.org/docs/help/tbb_userguide/parallel_reduce.htm

Also there is an overload of parallel_reduce which takes two functors - one for body and another one for merging partial results - as well as a special "identity" value used to initialize accumulators. But you are computing three aggregate values at once, so you would still need to have a struct or class to store all three values in a single variable.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top