Pipeline filter: Style

Pipeline filter: Style

Dear all,

I have a simple pipeline that should be constructed invoking some class methods. This is done because I'm using those methods serially for debugging purposes, but the style I'm using is horrible: having lambda wrappers:

    auto readerfn = [&](tbb::flow_control &flow)
    {
        return reader(flow);
    };
    
    auto correctorfn = [&](std::string s)
    {
        return corrector(s);
    };
    
    auto writerfn = [&](bool b)
    {
        writer(b);
    };
    
    // Start the pipeline
    tbb::parallel_pipeline(tokens,
                           tbb::make_filter<void, std::string>(tbb::filter::serial, readerfn) &
                           tbb::make_filter<std::string, bool>(tbb::filter::parallel, correctorfn) &
                           tbb::make_filter<bool, void>(tbb::filter::serial, writerfn));

Can you suggest a more acceptable way of making this thing work serially (not using the pipeline), and in parallel?

Thanks & Cheers!

6 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

This seems even more complicated than the example in the Reference Manual, which doesn't use separate variables for the lambdas, so I'm not sure what you mean...

Well, I'd like to avoid using those lambdas in that way: it's ugly :)

I already developed the serial code (methods in a class), and using the code in a pipeline isn't that cute.

Personnally, I like my pipelines to look this way:

 
// Start the pipeline
tbb::parallel_pipeline(
    tokens,
    tbb::make_filter<void, std::string>(
        tbb::filter::serial,
        [&](tbb::flow_control &flow) {
            return reader(flow);
        }) &
    tbb::make_filter<std::string, bool>(
        tbb::filter::parallel,
        [&](std::string s) {
            return corrector(s);
        }) &
    tbb::make_filter<bool, void>(
        tbb::filter::serial,
        [&](bool b) {
            writer(b);
        })
    );

 

You could whip up a macro to factor out the commonalities.

You could use "std::bind(&MyClass::reader, this, _1)" if you like that better than "[&] (tbb::flow_control &flow) { return reader(flow); }".

You could write a function template make_filter_from_functor() that determines the argument and result types of the functor and do "make_filter_from_functor(tbb::filter::serial, [&] (tbb::flow_control &flow) { return reader(flow); })". Have a look at boost::function_traits or somesuch. I wouldn't mind if TBB emulated that.

You could write a function template make_filter_from_memfn() combining ideas from the previous two and do "make_filter_from_memfn(tbb::filter::serial, &MyClass::reader, this)".

(2014-07-06 Edited) Replaced (non-technical) uses of "capture"(s) with "factor out" and "determines" to avoid confusion with lambda captures.

Thanks for all your comments!

Leave a Comment

Please sign in to add a comment. Not a member? Join today