gpt4 book ai didi

c++ - 通过引用 TBB 任务传递函数时无法返回值

转载 作者:行者123 更新时间:2023-11-28 05:03:21 25 4
gpt4 key购买 nike

我对英特尔 TBB 很感兴趣,我想弄清楚为什么当我也通过引用传递函数时,我无法填充通过引用传递给 TBB 任务的 vector 。

代码如下:

// tbbTesting.cpp : Defines the entry point for the console application.

#include "stdafx.h"

#include "tbb/task.h"

#include <functional>
#include <iostream>
#include <random>

#define NUM_POINTS 10


void myFunc(std::vector<double>& numbers)
{
std::mt19937_64 gen;
std::uniform_real_distribution<double> dis(0.0, 1000.0);

for (size_t i = 0; i < NUM_POINTS; i++)
{
auto val = dis(gen);
std::cout << val << std::endl; //proper values generated
numbers.push_back(val); //why is this failing?
}

std::cout << std::endl;

for (auto i : numbers)
{
std::cout << numbers[i] << std::endl; //garbage values
}
}


class TASK_generateRandomNumbers : public tbb::task
{
public:
TASK_generateRandomNumbers(std::function<void(std::vector<double>&)>& fnc,
std::vector<double>& nums) : _fnc(fnc), _numbers(nums) {}
~TASK_generateRandomNumbers() {};

tbb::task* execute()
{
_fnc(_numbers);
return nullptr;
}

private:
std::function<void(std::vector<double>&)>& _fnc;
std::vector<double>& _numbers;
};


class Manager
{
public:
Manager() { _numbers.reserve(NUM_POINTS); }
~Manager() {}

void GenerateNumbers()
{
_fnc = std::bind(&myFunc, _numbers);
TASK_generateRandomNumbers* t = new(tbb::task::allocate_root())
TASK_generateRandomNumbers(_fnc, _numbers);
tbb::task::spawn_root_and_wait(*t);
}

auto GetNumbers() const { return _numbers; }

private:
std::function<void(std::vector<double>&)> _fnc;
std::vector<double> _numbers;
};



int main()
{
Manager mgr;
mgr.GenerateNumbers();
auto numbers = mgr.GetNumbers(); //returns empty
}

execute 方法执行操作时,我可以通过引用传递 vector 时获取值。

execute 方法必须调用函数时,我将垃圾数据打印到控制台(push_back 失败?)并在返回时得到一个空容器。

任何人都可以看到我错过了什么吗?谢谢。

最佳答案

我发现了几个与 tbb 无关的错误。

1) 您的 myFunc 使用范围不正确。它不返回索引,而是直接依次返回 vector 中的每个值。您的代码将每个 double 转换为一个 int 并将其用作数组的索引,这就是您变得垃圾的原因。

2) 当您使用 std::bind 创建仿函数时,参数按值复制。如果你想传入一个引用,那么你需要使用 std::ref 来包装参数。

如果您使用的是 c++11,那么您可能要考虑使用 lambda 而不是绑定(bind)。

我以不同的方式使用您的 myFunc 编写了一个小程序:使用和不使用 std::ref 以及一个 lambda 示例。您应该看到它生成了 3 次相同的数字,但是当它尝试打印出 v1 时,它不会包含任何内容,因为生成的值被放置在一个拷贝中。

#include <vector>
#include <random>
#include <iostream>
#include <functional>

constexpr size_t NUM_POINTS = 10;

void myFunc(std::vector<double>& numbers)
{
std::mt19937_64 gen;
std::uniform_real_distribution<double> dis(0.0, 1000.0);

for (size_t i = 0; i < NUM_POINTS; i++)
{
auto val = dis(gen);
std::cout << val << std::endl; //proper values generated
numbers.push_back(val); //why is this failing? it's not
}

std::cout << std::endl;
}

void printNumbers(std::vector<double>const& numbers)
{
for (auto number : numbers)
{
std::cout << number << std::endl;
}
std::cout << std::endl;
}

int main()
{
std::cout << "generating v1" << std::endl;
std::vector<double> v1;
auto f1 = std::bind(&myFunc, v1);
f1();
printNumbers(v1);

std::cout << "generating v2" << std::endl;
std::vector<double> v2;
auto f2= std::bind(&myFunc, std::ref(v2));
f2();
printNumbers(v2);

std::cout << "generating v3" << std::endl;
std::vector<double> v3;
auto f3 = [&v3]() { myFunc(v3); }; //using a lambda
f3();
printNumbers(v3);

return 0;
}

关于c++ - 通过引用 TBB 任务传递函数时无法返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45404222/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com