Computing Pi - how to use lambda expression

Computing Pi - how to use lambda expression

Hi, every one.

I want to calculate PI using multi-core parallel algorithms. I have following code:

It seems to work well, but I can't write this with lambda expression.I tried to use example from this topic, but still something is wrong.. Please, show me how it could be look like..

#include <stdio.h>
#include <tbb/blocked_range.h>
#include <tbb/parallel_reduce.h>
#include <tbb/task_scheduler_init.h>
class Pi_MC
{
private:
    long num_steps;
    double step;
public:
  
    double pi;
    void operator () (const tbb::blocked_range<long> &r) 
    {
        double x, sum = 0.0;
        long end = r.end();
        for (int i = r.begin(); i != end; i++)
        {
            x = (i - 0.5) * step;
            sum = sum + 4.0 / (1.0 + x*x);
        }
        pi += sum * step;
    }
    void join(Pi_MC &p)
    {
        pi += p.pi;
    }
    Pi_MC(Pi_MC &p, tbb::split)
    {
        pi = 0.0;
        num_steps = p.num_steps;
        step = p.step;
    }
    Pi_MC(long n)
    {
        pi = 0.0;
        num_steps = n;
        step = 1.0 / (double) num_steps;
    }
};
int main()
{
    tbb::task_scheduler_init init;
    const long n = 100000000;
    Pi_MC pi(n);
    tbb::parallel_reduce(tbb::blocked_range<long>(0, n, 1000000), pi);
    printf ("Pi = %.16f steps: %d n", pi.pi, n);
    system("pause");    
}

7 posts / novo 0
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.

Something like this perhaps (not tested):


#include <stdio.h>

#include <functional>

#include <tbb/blocked_range.h>

#include <tbb/parallel_reduce.h>
int main() {

    const long num_steps = 100000000;

    const double step = 1.0 / num_steps;

    const double result = tbb::parallel_reduce(

        tbb::blocked_range<long>(0, num_steps),

        0.0,

        [] (const tbb::blocked_range<long> &r, const double value) -> double {

            double sum = 0.0;

            for (int i = r.begin(), end = r.end(); i != end; i++) {

                const double x = (i - 0.5) * step;

                sum += 4.0 / (1.0 + x*x);

            }

            return value + sum * step;

        },

        std::plus<double>()

    );

    printf ("Pi = %.16f steps: %d n", result, num_steps);

    system("pause");

}

Edited on 2013-01-02, after next 3 postings: added missing "#include <functional>", and another self-indulgent "const" with the "value" parameter ("const" should have been the default all along, and "var" should have been an additional keyword...).

This code didn't want to be accepted:


std::plus()

replaced it:


 []( double s1, double s2 ) { return s1+s2; }

and Viola!

Happy 2013!

Did you use "#include <functional>"? I'll assume that the template argument failed to show up because you wrote "std::plus<double>()" instead of the workaround syntax "std::plus&lt;double&gt;()" to assure correct visualisation in this forum.

I didnt have include.. Works! ;)

Now for a finishing touch: does the following work instead of that for loop to determine "sum" (with "#include <numeric>", of course)?


const double sum = std::accumulate(r.begin(), r.end(), 0.0,

    [] (const double acc, const long i) -> double {

        const double x = (i - 0.5) * step;

        return acc + 4.0 / (1.0 + x*x);

    });

Actually using that might be a bit pedantic, though, as it doesn't really make the code more concise... although perhaps it does illustrate intent a little bit better. It could also be interesting to compare timing results, because it seems more challenging to optimise around that lambda than with a straightforward loop.

Ok, thx for advice!

Deixar um comentário

Faça login para adicionar um comentário. Não é membro? Inscreva-se hoje mesmo!