0

我正在尝试从 https://software.intel.com/content/www/us/en/develop/blogs/a-feature-detection-example-using-the-intel-threading-building-blocks修改此示例-flow-graph.html

这个想法是我有一个应用于每个输入的“预处理”函数,以及一个应用于每对预处理输入的“处理”函数,扫描流。在我的示例中,我们最终只是计算了连续平方数之间的差异。

我下面的例子不起作用。我相信这是因为缓冲区在开始时是空的。在博客示例中,它们会在某个时候填充缓冲区。打电话buffer.try_put(0)似乎并不能解决我的问题。我错过了什么?还有什么更好的方法可以让流程自然地工作,简单地忽略由于缓冲区为空而无法完全处理的第一个元素?

#include <cstring>
#include <iostream>

#include "tbb/flow_graph.h"

using namespace tbb;
using namespace tbb::flow;

const int N = 13;


template<typename T>
class source_body {

    unsigned my_count;
    int *ninvocations;

public:

    source_body() : ninvocations(NULL) { my_count = 0; }

    source_body(int &_inv) : ninvocations(&_inv) { my_count = 0; }

    bool operator()(T &v) {
        v = (T) my_count++;
        if (ninvocations) ++(*ninvocations);
        if ((int) v < N)
            return true;
        else
            return false;
    }

};

int main() {
    graph g;

    typedef std::tuple<int32_t, int32_t> resource_tuple;

    queue_node<int> buffer(g);
    join_node<resource_tuple, reserving> resource_join(g);

    tbb::flow::source_node<int> src3(g, source_body<int>());
    src3.activate();

    function_node<int, int>
            preprocess_function(g, unlimited,
                                [](const int &a) -> int {

                                    return a * a;
                                }
    );

    make_edge(src3, preprocess_function);

    make_edge(preprocess_function, input_port<1>(resource_join));
    make_edge(preprocess_function, buffer);
    make_edge(buffer, input_port<0>(resource_join));

    function_node<resource_tuple, int>
            process_function(g, unlimited,
                             [](const resource_tuple &a) -> int {
                                 return std::get<1>(a) - std::get<0>(a);
                             }
    );
    make_edge(resource_join, process_function);


    function_node<int> printint(g, serial,
                               [](const int &t) -> void {
                                   std::cout << t << '\n';
                               }
    );
    make_edge(process_function, printint);

    buffer.try_put(0);
    g.wait_for_all();

    return 0;
}
4

1 回答 1

0

以下代码有效。替换reservingqueueing成功了。不过,并没有真正忽略第一个无法处理的元素。仍然很想知道在 TBB 图中实现这种“扫描”的最佳方法是什么。

#include <cstring>
#include <iostream>

#include "tbb/flow_graph.h"

using namespace tbb;
using namespace tbb::flow;

const int N = 13;


template<typename T>
class source_body {

    unsigned my_count;
    int *ninvocations;

public:

    source_body() : ninvocations(NULL) { my_count = 0; }

    source_body(int &_inv) : ninvocations(&_inv) { my_count = 0; }

    bool operator()(T &v) {
        v = (T) my_count++;
        if (ninvocations) ++(*ninvocations);
        if ((int) v < N)
            return true;
        else
            return false;
    }

};

int main() {
    graph g;

    typedef std::tuple<int32_t, int32_t> resource_tuple;

    queue_node<int> buffer(g);
    join_node<resource_tuple, queueing> resource_join(g);

    tbb::flow::source_node<int> src3(g, source_body<int>());
    src3.activate();

    function_node<int, int>
            preprocess_function(g, unlimited,
                                [](const int &a) -> int {

                                    return a * a;
                                }
    );

    make_edge(src3, preprocess_function);

    make_edge(preprocess_function, input_port<1>(resource_join));
    make_edge(preprocess_function, buffer);
    make_edge(buffer, input_port<0>(resource_join));

    function_node<resource_tuple, int>
            process_function(g, unlimited,
                             [](const resource_tuple &a) -> int {
                                 return std::get<1>(a) - std::get<0>(a);
                             }
    );
    make_edge(resource_join, process_function);

    function_node<int> printint(g, serial,
                                [](const int &t) -> void {
                                    std::cout << t << '\n';
                                }
    );

    make_edge(process_function, printint);

    buffer.try_put(0);
    g.wait_for_all();

    return 0;
}
于 2020-08-29T18:42:12.983 回答