commit
b4eb0c233d
|
@ -57,9 +57,8 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#ifdef GTSAM_USE_TBB
|
#ifdef GTSAM_USE_TBB
|
||||||
#include <tbb/tbb.h>
|
#include <tbb/task_arena.h> // tbb::task_arena
|
||||||
#undef max // TBB seems to include windows.h and we don't want these macros
|
#include <tbb/task_group.h> // tbb::task_group
|
||||||
#undef min
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -205,10 +204,11 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GTSAM_USE_TBB
|
#ifdef GTSAM_USE_TBB
|
||||||
std::unique_ptr<tbb::task_scheduler_init> init;
|
tbb::task_arena arena;
|
||||||
|
tbb::task_group tg;
|
||||||
if(nThreads > 0) {
|
if(nThreads > 0) {
|
||||||
cout << "Using " << nThreads << " threads" << endl;
|
cout << "Using " << nThreads << " threads" << endl;
|
||||||
init.reset(new tbb::task_scheduler_init(nThreads));
|
arena.initialize(nThreads);
|
||||||
} else
|
} else
|
||||||
cout << "Using threads for all processors" << endl;
|
cout << "Using threads for all processors" << endl;
|
||||||
#else
|
#else
|
||||||
|
@ -218,6 +218,10 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef GTSAM_USE_TBB
|
||||||
|
arena.execute([&]{
|
||||||
|
tg.run_and_wait([&]{
|
||||||
|
#endif
|
||||||
// Run mode
|
// Run mode
|
||||||
if(incremental)
|
if(incremental)
|
||||||
runIncremental();
|
runIncremental();
|
||||||
|
@ -229,6 +233,10 @@ int main(int argc, char *argv[]) {
|
||||||
runPerturb();
|
runPerturb();
|
||||||
else if(stats)
|
else if(stats)
|
||||||
runStats();
|
runStats();
|
||||||
|
#ifdef GTSAM_USE_TBB
|
||||||
|
});
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,12 @@ using boost::assign::list_of;
|
||||||
|
|
||||||
#ifdef GTSAM_USE_TBB
|
#ifdef GTSAM_USE_TBB
|
||||||
|
|
||||||
#include <tbb/tbb.h>
|
#include <tbb/blocked_range.h> // tbb::blocked_range
|
||||||
#undef max // TBB seems to include windows.h and we don't want these macros
|
#include <tbb/tick_count.h> // tbb::tick_count
|
||||||
#undef min
|
#include <tbb/parallel_for.h> // tbb::parallel_for
|
||||||
|
#include <tbb/cache_aligned_allocator.h> // tbb::cache_aligned_allocator
|
||||||
|
#include <tbb/task_arena.h> // tbb::task_arena
|
||||||
|
#include <tbb/task_group.h> // tbb::task_group
|
||||||
|
|
||||||
static const DenseIndex numberOfProblems = 1000000;
|
static const DenseIndex numberOfProblems = 1000000;
|
||||||
static const DenseIndex problemSize = 4;
|
static const DenseIndex problemSize = 4;
|
||||||
|
@ -67,10 +70,14 @@ struct WorkerWithoutAllocation
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
map<int, double> testWithoutMemoryAllocation()
|
map<int, double> testWithoutMemoryAllocation(int num_threads)
|
||||||
{
|
{
|
||||||
// A function to do some matrix operations without allocating any memory
|
// 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
|
// Now call it
|
||||||
vector<double> results(numberOfProblems);
|
vector<double> results(numberOfProblems);
|
||||||
|
|
||||||
|
@ -79,7 +86,14 @@ map<int, double> testWithoutMemoryAllocation()
|
||||||
for(size_t grainSize: grainSizes)
|
for(size_t grainSize: grainSizes)
|
||||||
{
|
{
|
||||||
tbb::tick_count t0 = tbb::tick_count::now();
|
tbb::tick_count t0 = tbb::tick_count::now();
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(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<size_t>(0, numberOfProblems), WorkerWithoutAllocation(results));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
tbb::tick_count t1 = tbb::tick_count::now();
|
tbb::tick_count t1 = tbb::tick_count::now();
|
||||||
cout << "Without memory allocation, grain size = " << grainSize << ", time = " << (t1 - t0).seconds() << endl;
|
cout << "Without memory allocation, grain size = " << grainSize << ", time = " << (t1 - t0).seconds() << endl;
|
||||||
timingResults[(int)grainSize] = (t1 - t0).seconds();
|
timingResults[(int)grainSize] = (t1 - t0).seconds();
|
||||||
|
@ -120,10 +134,14 @@ struct WorkerWithAllocation
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
map<int, double> testWithMemoryAllocation()
|
map<int, double> testWithMemoryAllocation(int num_threads)
|
||||||
{
|
{
|
||||||
// A function to do some matrix operations with allocating memory
|
// 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
|
// Now call it
|
||||||
vector<double> results(numberOfProblems);
|
vector<double> results(numberOfProblems);
|
||||||
|
|
||||||
|
@ -132,7 +150,14 @@ map<int, double> testWithMemoryAllocation()
|
||||||
for(size_t grainSize: grainSizes)
|
for(size_t grainSize: grainSizes)
|
||||||
{
|
{
|
||||||
tbb::tick_count t0 = tbb::tick_count::now();
|
tbb::tick_count t0 = tbb::tick_count::now();
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(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<size_t>(0, numberOfProblems), WorkerWithAllocation(results));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
tbb::tick_count t1 = tbb::tick_count::now();
|
tbb::tick_count t1 = tbb::tick_count::now();
|
||||||
cout << "With memory allocation, grain size = " << grainSize << ", time = " << (t1 - t0).seconds() << endl;
|
cout << "With memory allocation, grain size = " << grainSize << ", time = " << (t1 - t0).seconds() << endl;
|
||||||
timingResults[(int)grainSize] = (t1 - t0).seconds();
|
timingResults[(int)grainSize] = (t1 - t0).seconds();
|
||||||
|
@ -153,9 +178,8 @@ int main(int argc, char* argv[])
|
||||||
for(size_t n: numThreads)
|
for(size_t n: numThreads)
|
||||||
{
|
{
|
||||||
cout << "With " << n << " threads:" << endl;
|
cout << "With " << n << " threads:" << endl;
|
||||||
tbb::task_scheduler_init init((int)n);
|
results[(int)n].grainSizesWithoutAllocation = testWithoutMemoryAllocation((int)n);
|
||||||
results[(int)n].grainSizesWithoutAllocation = testWithoutMemoryAllocation();
|
results[(int)n].grainSizesWithAllocation = testWithMemoryAllocation((int)n);
|
||||||
results[(int)n].grainSizesWithAllocation = testWithMemoryAllocation();
|
|
||||||
cout << endl;
|
cout << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file ThreadSafeException.h
|
* @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
|
* @author Richard Roberts
|
||||||
* @date Aug 21, 2010
|
* @date Aug 21, 2010
|
||||||
* @addtogroup base
|
* @addtogroup base
|
||||||
|
@ -25,34 +25,28 @@
|
||||||
#include <gtsam/dllexport.h>
|
#include <gtsam/dllexport.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
#ifdef GTSAM_USE_TBB
|
#ifdef GTSAM_USE_TBB
|
||||||
#include <tbb/tbb_allocator.h>
|
#include <tbb/tbb_allocator.h>
|
||||||
#include <tbb/tbb_exception.h>
|
|
||||||
#include <tbb/scalable_allocator.h>
|
#include <tbb/scalable_allocator.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace gtsam {
|
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 DERIVED>
|
template<class DERIVED>
|
||||||
class ThreadsafeException:
|
class ThreadsafeException:
|
||||||
#ifdef GTSAM_USE_TBB
|
|
||||||
public tbb::tbb_exception
|
|
||||||
#else
|
|
||||||
public std::exception
|
public std::exception
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
#ifdef GTSAM_USE_TBB
|
|
||||||
private:
|
private:
|
||||||
typedef tbb::tbb_exception Base;
|
typedef std::exception Base;
|
||||||
|
#ifdef GTSAM_USE_TBB
|
||||||
protected:
|
protected:
|
||||||
typedef std::basic_string<char, std::char_traits<char>,
|
typedef std::basic_string<char, std::char_traits<char>,
|
||||||
tbb::tbb_allocator<char> > String;
|
tbb::tbb_allocator<char> > String;
|
||||||
#else
|
#else
|
||||||
private:
|
|
||||||
typedef std::exception Base;
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::string String;
|
typedef std::string String;
|
||||||
#endif
|
#endif
|
||||||
|
@ -82,36 +76,6 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
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<DERIVED&>(*this));
|
|
||||||
clone->dynamic_ = true;
|
|
||||||
return clone;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void destroy() throw () {
|
|
||||||
if (dynamic_) {
|
|
||||||
DERIVED* derivedPtr = static_cast<DERIVED*>(this);
|
|
||||||
derivedPtr->~DERIVED();
|
|
||||||
scalable_free(derivedPtr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void throw_self() {
|
|
||||||
throw *static_cast<DERIVED*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const char* name() const throw () {
|
|
||||||
return typeid(DERIVED).name();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
virtual const char* what() const throw () {
|
virtual const char* what() const throw () {
|
||||||
return description_ ? description_->c_str() : "";
|
return description_ ? description_->c_str() : "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include <gtsam/config.h> // for GTSAM_USE_TBB
|
#include <gtsam/config.h> // for GTSAM_USE_TBB
|
||||||
|
|
||||||
#ifdef GTSAM_USE_TBB
|
#ifdef GTSAM_USE_TBB
|
||||||
#include <tbb/mutex.h>
|
#include <mutex> // std::mutex, std::unique_lock
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
@ -28,13 +28,13 @@ namespace gtsam {
|
||||||
GTSAM_EXPORT FastMap<std::string, ValueWithDefault<bool, false> > debugFlags;
|
GTSAM_EXPORT FastMap<std::string, ValueWithDefault<bool, false> > debugFlags;
|
||||||
|
|
||||||
#ifdef GTSAM_USE_TBB
|
#ifdef GTSAM_USE_TBB
|
||||||
tbb::mutex debugFlagsMutex;
|
std::mutex debugFlagsMutex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
bool guardedIsDebug(const std::string& s) {
|
bool guardedIsDebug(const std::string& s) {
|
||||||
#ifdef GTSAM_USE_TBB
|
#ifdef GTSAM_USE_TBB
|
||||||
tbb::mutex::scoped_lock lock(debugFlagsMutex);
|
std::unique_lock<std::mutex> lock(debugFlagsMutex);
|
||||||
#endif
|
#endif
|
||||||
return gtsam::debugFlags[s];
|
return gtsam::debugFlags[s];
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ bool guardedIsDebug(const std::string& s) {
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void guardedSetDebug(const std::string& s, const bool v) {
|
void guardedSetDebug(const std::string& s, const bool v) {
|
||||||
#ifdef GTSAM_USE_TBB
|
#ifdef GTSAM_USE_TBB
|
||||||
tbb::mutex::scoped_lock lock(debugFlagsMutex);
|
std::unique_lock<std::mutex> lock(debugFlagsMutex);
|
||||||
#endif
|
#endif
|
||||||
gtsam::debugFlags[s] = v;
|
gtsam::debugFlags[s] = v;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,8 @@
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
|
|
||||||
#ifdef GTSAM_USE_TBB
|
#ifdef GTSAM_USE_TBB
|
||||||
# include <tbb/tbb.h>
|
#include <tbb/task.h> // tbb::task, tbb::task_list
|
||||||
# include <tbb/scalable_allocator.h>
|
#include <tbb/scalable_allocator.h> // tbb::scalable_allocator
|
||||||
# undef max // TBB seems to include windows.h and we don't want these macros
|
|
||||||
# undef min
|
|
||||||
# undef ERROR
|
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,9 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
#ifdef GTSAM_USE_TBB
|
#ifdef GTSAM_USE_TBB
|
||||||
#include <tbb/task_scheduler_init.h>
|
|
||||||
#include <tbb/tbb_exception.h>
|
|
||||||
#include <tbb/scalable_allocator.h>
|
#include <tbb/scalable_allocator.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -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
|
// 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.
|
// 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.
|
// 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<std::mutex> lock(B_mutex_);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const bool cachedBasis = static_cast<bool>(B_);
|
const bool cachedBasis = static_cast<bool>(B_);
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#ifdef GTSAM_USE_TBB
|
#ifdef GTSAM_USE_TBB
|
||||||
#include <tbb/mutex.h>
|
#include <mutex> // std::mutex
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
@ -48,7 +48,7 @@ private:
|
||||||
mutable boost::optional<Matrix62> H_B_; ///< Cached basis derivative
|
mutable boost::optional<Matrix62> H_B_; ///< Cached basis derivative
|
||||||
|
|
||||||
#ifdef GTSAM_USE_TBB
|
#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
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue