【问题标题】:Lambda form of tbb::parallel_reduce: constness in second rhs argument of reduce functiontbb::parallel_reduce 的 Lambda 形式:reduce 函数的第二个 rhs 参数中的常量
【发布时间】:2016-05-20 13:15:09
【问题描述】:

我正在尝试使用 parallel_reduce 并行构建直方图:

#include "stdint.h"
#include "tbb/tbb.h"
#include <algorithm>
#include <vector>
#include <functional>
#include <iostream>
#include <numeric>


void buildhistogram(const uint8_t *inputImage, const size_t numElements, double *outputHist){

    auto range = tbb::blocked_range<size_t>(0,numElements);
    auto buildHistogramFcn = [&](const tbb::blocked_range<size_t>& r, const std::vector<double>& initHist){
                            std::vector<double> localHist(initHist);
                            for (size_t idx = r.begin(); idx != r.end(); ++idx){
                                localHist[inputImage[idx]]++;
                             }
                             return localHist;
};

auto reductionFcn = [&](const std::vector<double>& hist1, const std::vector<double>& hist2){
    std::vector<double> histOut(hist1.size());
    std::transform(hist1.begin(),hist1.end(),hist2.begin(),histOut.begin(),std::plus<double>());
    return histOut;
};

std::vector<double> identity(256);
auto output = tbb::parallel_reduce(range, identity, buildHistogramFcn, reductionFcn);

std::copy(output.begin(),output.end(),outputHist);
}

我的问题涉及以parallel_reduce 的lambda 形式定义Func。如果您查看英特尔文档:

https://software.intel.com/en-us/node/506154

他们将 Func 的第二个 RHS 参数记录为 const:

Value Func::operator()(const Range& range, const Value& x)

但是,如果您查看他们的示例代码,他们会定义一个示例,其中第二个 RHS 是非常量的,实际上他们修改并返回了这个变量:

auto intelExampleFcn = [](const blocked_range<float*>& r, float init)->float {
        for( float* a=r.begin(); a!=r.end(); ++a )
            init += *a;
        return init;
  };

如果我尝试将变量“initHist”声明为非常量并直接使用此内存而不分配和返回本地副本:

auto buildHistogramFcn = [&](const tbb::blocked_range<size_t>& r, std::vector<double>& initHist){
                        for (size_t idx = r.begin(); idx != r.end(); ++idx){
                            initHist[inputImage[idx]]++;
                         }
                         return initHist;
}; 

我得到一个编译错误:

/tbb/include/tbb/parallel_reduce.h:322:24: 错误:没有匹配函数调用类型为“const (lambda at buildhistogramTBB.cpp:16:30)”的对象 my_value = my_real_body(range, const_cast(my_value));

我对 lambda 的第二个 RHS 参数是否实际上可以是非常量感兴趣,因为我希望能够避免将向量从 init 参数复制到我返回的局部变量.

是我误解了什么,还是英特尔的例子不正确?

【问题讨论】:

  • "如果我尝试将变量 "init" 声明为非常量" 你能演示一下吗?
  • 在我的示例中已编辑以演示 buildHistogramFcn 的非常量第二个 RHS 参数形式。对缺乏明确性表示歉意。

标签: c++ c++11 lambda tbb


【解决方案1】:

英特尔示例中的第二个“非常量”参数是按值传递的。如果您要通过值(而不是通过引用)传递您的initHist 向量,它也不需要const。 (当然,它会复制向量。但这似乎就是你正在做的事情。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-04
    • 2021-12-20
    • 2016-10-04
    相关资源
    最近更新 更多