diff --git a/examples/SolverComparer.cpp b/examples/SolverComparer.cpp index 991be348c..12e69d9de 100644 --- a/examples/SolverComparer.cpp +++ b/examples/SolverComparer.cpp @@ -57,9 +57,8 @@ #include #ifdef GTSAM_USE_TBB -#include -#undef max // TBB seems to include windows.h and we don't want these macros -#undef min +#include // tbb::task_arena +#include // tbb::task_group #endif using namespace std; @@ -205,10 +204,11 @@ int main(int argc, char *argv[]) { } #ifdef GTSAM_USE_TBB - std::unique_ptr init; + tbb::task_arena arena; + tbb::task_group tg; if(nThreads > 0) { cout << "Using " << nThreads << " threads" << endl; - init.reset(new tbb::task_scheduler_init(nThreads)); + arena.initialize(nThreads); } else cout << "Using threads for all processors" << endl; #else @@ -218,6 +218,10 @@ int main(int argc, char *argv[]) { } #endif +#ifdef GTSAM_USE_TBB + arena.execute([&]{ + tg.run_and_wait([&]{ +#endif // Run mode if(incremental) runIncremental(); @@ -229,6 +233,10 @@ int main(int argc, char *argv[]) { runPerturb(); else if(stats) runStats(); +#ifdef GTSAM_USE_TBB + }); + }); +#endif return 0; } diff --git a/examples/TimeTBB.cpp b/examples/TimeTBB.cpp index 178fa513f..4bc5144f4 100644 --- a/examples/TimeTBB.cpp +++ b/examples/TimeTBB.cpp @@ -28,9 +28,12 @@ using boost::assign::list_of; #ifdef GTSAM_USE_TBB -#include -#undef max // TBB seems to include windows.h and we don't want these macros -#undef min +#include // tbb::blocked_range +#include // tbb::tick_count +#include // tbb::parallel_for +#include // tbb::cache_aligned_allocator +#include // tbb::task_arena +#include // tbb::task_group static const DenseIndex numberOfProblems = 1000000; static const DenseIndex problemSize = 4; @@ -67,10 +70,14 @@ struct WorkerWithoutAllocation }; /* ************************************************************************* */ -map testWithoutMemoryAllocation() +map testWithoutMemoryAllocation(int num_threads) { // A function to do some matrix operations without allocating any memory + // Create task_arena and task_group + tbb::task_arena arena(num_threads); + tbb::task_group tg; + // Now call it vector results(numberOfProblems); @@ -79,7 +86,14 @@ map testWithoutMemoryAllocation() for(size_t grainSize: grainSizes) { tbb::tick_count t0 = tbb::tick_count::now(); - tbb::parallel_for(tbb::blocked_range(0, numberOfProblems), WorkerWithoutAllocation(results)); + + // Run parallel code (as a task group) inside of task arena + arena.execute([&]{ + tg.run_and_wait([&]{ + tbb::parallel_for(tbb::blocked_range(0, numberOfProblems), WorkerWithoutAllocation(results)); + }); + }); + tbb::tick_count t1 = tbb::tick_count::now(); cout << "Without memory allocation, grain size = " << grainSize << ", time = " << (t1 - t0).seconds() << endl; timingResults[(int)grainSize] = (t1 - t0).seconds(); @@ -120,10 +134,14 @@ struct WorkerWithAllocation }; /* ************************************************************************* */ -map testWithMemoryAllocation() +map testWithMemoryAllocation(int num_threads) { // A function to do some matrix operations with allocating memory + // Create task_arena and task_group + tbb::task_arena arena(num_threads); + tbb::task_group tg; + // Now call it vector results(numberOfProblems); @@ -132,7 +150,14 @@ map testWithMemoryAllocation() for(size_t grainSize: grainSizes) { tbb::tick_count t0 = tbb::tick_count::now(); - tbb::parallel_for(tbb::blocked_range(0, numberOfProblems), WorkerWithAllocation(results)); + + // Run parallel code (as a task group) inside of task arena + arena.execute([&]{ + tg.run_and_wait([&]{ + tbb::parallel_for(tbb::blocked_range(0, numberOfProblems), WorkerWithAllocation(results)); + }); + }); + tbb::tick_count t1 = tbb::tick_count::now(); cout << "With memory allocation, grain size = " << grainSize << ", time = " << (t1 - t0).seconds() << endl; timingResults[(int)grainSize] = (t1 - t0).seconds(); @@ -153,9 +178,8 @@ int main(int argc, char* argv[]) for(size_t n: numThreads) { cout << "With " << n << " threads:" << endl; - tbb::task_scheduler_init init((int)n); - results[(int)n].grainSizesWithoutAllocation = testWithoutMemoryAllocation(); - results[(int)n].grainSizesWithAllocation = testWithMemoryAllocation(); + results[(int)n].grainSizesWithoutAllocation = testWithoutMemoryAllocation((int)n); + results[(int)n].grainSizesWithAllocation = testWithMemoryAllocation((int)n); cout << endl; } diff --git a/gtsam/base/ThreadsafeException.h b/gtsam/base/ThreadsafeException.h index 15a76fbf1..0f7c6131d 100644 --- a/gtsam/base/ThreadsafeException.h +++ b/gtsam/base/ThreadsafeException.h @@ -11,7 +11,7 @@ /** * @file ThreadSafeException.h - * @brief Base exception type that uses tbb_exception if GTSAM is compiled with TBB + * @brief Base exception type that uses tbb_allocator if GTSAM is compiled with TBB * @author Richard Roberts * @date Aug 21, 2010 * @addtogroup base @@ -25,34 +25,28 @@ #include #include #include +#include #ifdef GTSAM_USE_TBB #include -#include #include #include #endif namespace gtsam { -/// Base exception type that uses tbb_exception if GTSAM is compiled with TBB. +/// Base exception type that uses tbb_allocator if GTSAM is compiled with TBB. template class ThreadsafeException: -#ifdef GTSAM_USE_TBB - public tbb::tbb_exception -#else public std::exception -#endif { -#ifdef GTSAM_USE_TBB private: - typedef tbb::tbb_exception Base; + typedef std::exception Base; +#ifdef GTSAM_USE_TBB protected: typedef std::basic_string, tbb::tbb_allocator > String; #else -private: - typedef std::exception Base; protected: typedef std::string String; #endif @@ -82,36 +76,6 @@ protected: } public: - // Implement functions for tbb_exception -#ifdef GTSAM_USE_TBB - virtual tbb::tbb_exception* move() throw () { - void* cloneMemory = scalable_malloc(sizeof(DERIVED)); - if (!cloneMemory) { - std::cerr << "Failed allocating memory to copy thrown exception, exiting now." << std::endl; - exit(-1); - } - DERIVED* clone = ::new(cloneMemory) DERIVED(static_cast(*this)); - clone->dynamic_ = true; - return clone; - } - - virtual void destroy() throw () { - if (dynamic_) { - DERIVED* derivedPtr = static_cast(this); - derivedPtr->~DERIVED(); - scalable_free(derivedPtr); - } - } - - virtual void throw_self() { - throw *static_cast(this); - } - - virtual const char* name() const throw () { - return typeid(DERIVED).name(); - } -#endif - virtual const char* what() const throw () { return description_ ? description_->c_str() : ""; } diff --git a/gtsam/base/debug.cpp b/gtsam/base/debug.cpp index d6d2a4fe0..592b42d15 100644 --- a/gtsam/base/debug.cpp +++ b/gtsam/base/debug.cpp @@ -20,7 +20,7 @@ #include // for GTSAM_USE_TBB #ifdef GTSAM_USE_TBB -#include +#include // std::mutex, std::unique_lock #endif namespace gtsam { @@ -28,13 +28,13 @@ namespace gtsam { GTSAM_EXPORT FastMap > debugFlags; #ifdef GTSAM_USE_TBB -tbb::mutex debugFlagsMutex; +std::mutex debugFlagsMutex; #endif /* ************************************************************************* */ bool guardedIsDebug(const std::string& s) { #ifdef GTSAM_USE_TBB - tbb::mutex::scoped_lock lock(debugFlagsMutex); + std::unique_lock lock(debugFlagsMutex); #endif return gtsam::debugFlags[s]; } @@ -42,7 +42,7 @@ bool guardedIsDebug(const std::string& s) { /* ************************************************************************* */ void guardedSetDebug(const std::string& s, const bool v) { #ifdef GTSAM_USE_TBB - tbb::mutex::scoped_lock lock(debugFlagsMutex); + std::unique_lock lock(debugFlagsMutex); #endif gtsam::debugFlags[s] = v; } diff --git a/gtsam/base/treeTraversal/parallelTraversalTasks.h b/gtsam/base/treeTraversal/parallelTraversalTasks.h index db3181b87..b9eaea1c4 100644 --- a/gtsam/base/treeTraversal/parallelTraversalTasks.h +++ b/gtsam/base/treeTraversal/parallelTraversalTasks.h @@ -22,11 +22,8 @@ #include #ifdef GTSAM_USE_TBB -# include -# include -# undef max // TBB seems to include windows.h and we don't want these macros -# undef min -# undef ERROR +#include // tbb::task, tbb::task_list +#include // tbb::scalable_allocator namespace gtsam { diff --git a/gtsam/base/types.h b/gtsam/base/types.h index 3b6c9f337..d12a4209a 100644 --- a/gtsam/base/types.h +++ b/gtsam/base/types.h @@ -27,9 +27,9 @@ #include #include +#include + #ifdef GTSAM_USE_TBB -#include -#include #include #endif diff --git a/gtsam/geometry/Unit3.cpp b/gtsam/geometry/Unit3.cpp old mode 100755 new mode 100644 index 3d46b18b8..6f70d840e --- a/gtsam/geometry/Unit3.cpp +++ b/gtsam/geometry/Unit3.cpp @@ -78,7 +78,7 @@ const Matrix32& Unit3::basis(OptionalJacobian<6, 2> H) const { // NOTE(hayk): At some point it seemed like this reproducably resulted in // deadlock. However, I don't know why and I can no longer reproduce it. // It either was a red herring or there is still a latent bug left to debug. - tbb::mutex::scoped_lock lock(B_mutex_); + std::unique_lock lock(B_mutex_); #endif const bool cachedBasis = static_cast(B_); diff --git a/gtsam/geometry/Unit3.h b/gtsam/geometry/Unit3.h index 1c6945c4c..f1a9c1a69 100644 --- a/gtsam/geometry/Unit3.h +++ b/gtsam/geometry/Unit3.h @@ -33,7 +33,7 @@ #include #ifdef GTSAM_USE_TBB -#include +#include // std::mutex #endif namespace gtsam { @@ -48,7 +48,7 @@ private: mutable boost::optional H_B_; ///< Cached basis derivative #ifdef GTSAM_USE_TBB - mutable tbb::mutex B_mutex_; ///< Mutex to protect the cached basis. + mutable std::mutex B_mutex_; ///< Mutex to protect the cached basis. #endif public: