tutorial open libro docs c++ tbb icc

c++ - open - Ejemplo más simple de TBB



opencv python 3 (4)

¿Puede alguien darme un ejemplo de TBB cómo:

  1. establecer el recuento máximo de subprocesos activos.
  2. Ejecuta tareas que son independientes entre sí y se presentan en forma de clase, no de funciones estáticas.

1-

//! //! Get the default number of threads //! int nDefThreads = tbb::task_scheduler_init::default_num_threads(); //! //! Init the task scheduler with the wanted number of threads //! tbb::task_scheduler_init init(nDefThreads);

2-

Tal vez si su código lo permite, la mejor manera de ejecutar una tarea independiente con TBB es el parallel_invoke . En el blog de la zona de desarrolladores de Intel hay una publicación que explica algunos casos de cuán útil podría ser el paralelismo. Mira this


Aquí hay un uso más moderno de parallel_for con una lambda; compila y ejecuta en Debian / Wheezy con g++ -std=c++11 tbb_example.cpp -ltbb && ./a.out :

#include "tbb/parallel_for.h" #include "tbb/task_scheduler_init.h" #include <iostream> #include <vector> struct mytask { mytask(size_t n) :_n(n) {} void operator()() { for (int i=0;i<1000000;++i) {} // Deliberately run slow std::cerr << "[" << _n << "]"; } size_t _n; }; int main(int,char**) { //tbb::task_scheduler_init init; // Automatic number of threads tbb::task_scheduler_init init(tbb::task_scheduler_init::default_num_threads()); // Explicit number of threads std::vector<mytask> tasks; for (int i=0;i<1000;++i) tasks.push_back(mytask(i)); tbb::parallel_for( tbb::blocked_range<size_t>(0,tasks.size()), [&tasks](const tbb::blocked_range<size_t>& r) { for (size_t i=r.begin();i<r.end();++i) tasks[i](); } ); std::cerr << std::endl; return 0; }


Si solo desea ejecutar un par de tareas a la vez, puede ser más fácil usar simplemente tbb::task_group . Ejemplo tomado de tbb :

#include "tbb/task_group.h" using namespace tbb; int Fib(int n) { if( n<2 ) { return n; } else { int x, y; task_group g; g.run([&]{x=Fib(n-1);}); // spawn a task g.run([&]{y=Fib(n-2);}); // spawn another task g.wait(); // wait for both tasks to complete return x+y; } }

Sin embargo, tenga en cuenta que

La creación de un gran número de tareas para un solo grupo de tareas no es escalable, ya que la creación de tareas se convierte en un cuello de botella en serie.

En esos casos, use los ejemplos de timday con un valor parallel_for o similar.


Aquí hay un par de ejemplos completos, uno usando parallel_for , el otro usando parallel_for_each .

Actualización 2014-04-12 : Estos muestran lo que consideraría una forma bastante anticuada de usar TBB ahora; He agregado una respuesta por separado usando parallel_for con un lambda C ++ 11.

#include "tbb/blocked_range.h" #include "tbb/parallel_for.h" #include "tbb/task_scheduler_init.h" #include <iostream> #include <vector> struct mytask { mytask(size_t n) :_n(n) {} void operator()() { for (int i=0;i<1000000;++i) {} // Deliberately run slow std::cerr << "[" << _n << "]"; } size_t _n; }; struct executor { executor(std::vector<mytask>& t) :_tasks(t) {} executor(executor& e,tbb::split) :_tasks(e._tasks) {} void operator()(const tbb::blocked_range<size_t>& r) const { for (size_t i=r.begin();i!=r.end();++i) _tasks[i](); } std::vector<mytask>& _tasks; }; int main(int,char**) { tbb::task_scheduler_init init; // Automatic number of threads // tbb::task_scheduler_init init(2); // Explicit number of threads std::vector<mytask> tasks; for (int i=0;i<1000;++i) tasks.push_back(mytask(i)); executor exec(tasks); tbb::parallel_for(tbb::blocked_range<size_t>(0,tasks.size()),exec); std::cerr << std::endl; return 0; }

y

#include "tbb/parallel_for_each.h" #include "tbb/task_scheduler_init.h" #include <iostream> #include <vector> struct mytask { mytask(size_t n) :_n(n) {} void operator()() { for (int i=0;i<1000000;++i) {} // Deliberately run slow std::cerr << "[" << _n << "]"; } size_t _n; }; template <typename T> struct invoker { void operator()(T& it) const {it();} }; int main(int,char**) { tbb::task_scheduler_init init; // Automatic number of threads // tbb::task_scheduler_init init(4); // Explicit number of threads std::vector<mytask> tasks; for (int i=0;i<1000;++i) tasks.push_back(mytask(i)); tbb::parallel_for_each(tasks.begin(),tasks.end(),invoker<mytask>()); std::cerr << std::endl; return 0; }

Ambos compilan en un sistema Debian / Wheezy (g ++ 4.7) con g++ tbb_example.cpp -ltbb (luego se ejecutan con ./a.out )

(Vea esta pregunta para reemplazar esa cosa de " invoker " con un std::mem_fun_ref o boost::bind ).