90 lines
2.4 KiB
C++
90 lines
2.4 KiB
C++
|
#include <iostream>
|
||
|
#include <chrono>
|
||
|
#include <omp.h>
|
||
|
|
||
|
#include "levelgraph.hpp"
|
||
|
#include <tbb/global_control.h>
|
||
|
#include <tbb/flow_graph.h>
|
||
|
|
||
|
using namespace tbb;
|
||
|
using namespace tbb::flow;
|
||
|
|
||
|
struct TBB {
|
||
|
|
||
|
TBB(LevelGraph& graph, unsigned num_threads) {
|
||
|
|
||
|
tbb::global_control c(
|
||
|
tbb::global_control::max_allowed_parallelism, num_threads
|
||
|
);
|
||
|
|
||
|
tasks.resize(graph.level());
|
||
|
for(size_t i=0; i<tasks.size(); ++i) {
|
||
|
tasks[i].resize(graph.length());
|
||
|
}
|
||
|
|
||
|
for(size_t i=0; i<graph.length(); i++){
|
||
|
Node& n = graph.node_at(graph.level()-1, i);
|
||
|
tasks[graph.level()-1][i] = std::make_unique<continue_node<continue_msg>>(G,
|
||
|
[&](const continue_msg&){ n.mark(); }
|
||
|
);
|
||
|
}
|
||
|
|
||
|
for(int l=graph.level()-2; l>=0 ; l--){
|
||
|
for(size_t i=0; i<graph.length(); i++){
|
||
|
Node& n = graph.node_at(l, i);
|
||
|
tasks[l][i] = std::make_unique<continue_node<continue_msg>>(G,
|
||
|
[&](const continue_msg&){ n.mark(); }
|
||
|
);
|
||
|
for(size_t k=0; k<n._out_edges.size(); k++){
|
||
|
make_edge(*tasks[l][i], *tasks[l+1][n._out_edges[k]]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
source = std::make_unique<continue_node<continue_msg>>(G,
|
||
|
[](const continue_msg&){}
|
||
|
);
|
||
|
|
||
|
for(int l=0; l>=0 ; l--) {
|
||
|
for(size_t i=0; i<graph.length(); i++){
|
||
|
make_edge(*source, *tasks[l][i]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void run() {
|
||
|
source->try_put(continue_msg());
|
||
|
G.wait_for_all();
|
||
|
}
|
||
|
|
||
|
tbb::flow::graph G;
|
||
|
std::vector<std::vector<std::unique_ptr<continue_node<continue_msg>>>> tasks;
|
||
|
std::unique_ptr<continue_node<continue_msg>> source;
|
||
|
};
|
||
|
|
||
|
void traverse_regular_graph_tbb(LevelGraph& graph, unsigned num_threads){
|
||
|
TBB tbb(graph, num_threads);
|
||
|
tbb.run();
|
||
|
}
|
||
|
|
||
|
std::chrono::microseconds measure_time_tbb(LevelGraph& graph, unsigned num_threads){
|
||
|
auto beg = std::chrono::high_resolution_clock::now();
|
||
|
traverse_regular_graph_tbb(graph, num_threads);
|
||
|
auto end = std::chrono::high_resolution_clock::now();
|
||
|
return std::chrono::duration_cast<std::chrono::microseconds>(end - beg);
|
||
|
}
|
||
|
|
||
|
//int main(int argc, char* argv[]){
|
||
|
//
|
||
|
// for(int i=1; i<=200; i++){
|
||
|
// LevelGraph graph(i, i);
|
||
|
// auto tbb = measure_time_tbb(graph);
|
||
|
// std::cout << "Level graph:\t" << i << "\tby\t" << i << std::endl;
|
||
|
// std::cout << "Elasped time tbb:\t" << tbb << std::endl;
|
||
|
// std::cout << "Graph is fully traversed:\t" << graph.validate_result() << std::endl;
|
||
|
// graph.clear_graph();
|
||
|
// std::cout << std::endl;
|
||
|
// }
|
||
|
//
|
||
|
//}
|