How can I change the std :: launch policy for std :: async?

Suppose I want to use std::async

parallelism in my C ++ code to run a heavy computational function func

. Now, since this is a heavy function, we can first use a policy for it std::launch::deferred

, since the situation is such that we may not need to run after all.

But if we ever need to fulfill them in the future, we will strive in parallel. Then how can we change the policy std::launch

.

[Well, you might say, why don't you create std::async

, when suddenly you need to execute. But I guess I can't.]

Or, is there a better and cleaner way to do this other than using it std::async

?

Any help is greatly appreciated. Thanks in advance.

#include <future>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <iostream>

std::vector<double> func(size_t n) // a computationally heavy function
{
    std::vector<double> vec(n);
    std::generate_n(vec.begin(), n, std::rand);
    return vec;
}

int main()
{
    // create asyncs, now deferred for lazy execution
    auto v1 = std::async(std::launch::deferred, func, 200); // deferred for lazy execution
    auto v2 = std::async(std::launch::deferred, func, 250); // deferred for lazy execution

    // only after sometime we decide to execute both of them
    // but we also now want them to execute in parallel

    // so how can we now change the launch policy?

    // to get the values as quickly as can be
    auto n1 = v1.get().size();
    auto n2 = v2.get().size();

    std::cout<<"Got "<<n1<<" and "<<n2<<" random numbers in parallel!"<<std::endl;
    return 0;
}

      

UPDATE

Thinking a little more leads me to this problem:

Once defined std::async

with std::launch::deferred

, when you call the function .get()

, then async is guaranteed to be executed (i.e. in parallel). Of course not. http://en.cppreference.com/w/cpp/thread/launch says

executed on the calling thread.

Then the very notion of async will screw up, right?

+3


source to share


1 answer


If std::async

used std::launch::deferred

, then it starts when you call the returned function std::future

object get()

.

This suggests that you can force it std::launch::async

like this:



int s1 = 0;
int s2 = 0;

auto v1 = std::async(std::launch::deferred, []{ return 1; });
auto v2 = std::async(std::launch::deferred, []{ return 2; });

// some fancy coding ...

if(need_to_upgrade_launch_policy())
{
    auto v1a = std::async(std::launch::async, [&]{ return v1.get(); });
    auto v2a = std::async(std::launch::async, [&]{ return v2.get(); });

    s1 = v1a.get();
    s2 = v2a.get();
}

//  more clever coding ...

if(v1.valid()) // was never upgraded
    s1 = v1.get();

if(v2.valid()) // was never upgraded
    s2 = v2.get();

      

+1


source







All Articles