mirror of https://github.com/CGAL/cgal
Benchmark
This commit is contained in:
parent
28c5fde142
commit
596c84ccb7
|
|
@ -0,0 +1,249 @@
|
|||
//#undef CGAL_LINKED_WITH_TBB
|
||||
|
||||
#include <CGAL/tags.h>
|
||||
#include <CGAL/Compact_container.h>
|
||||
#include <CGAL/Real_timer.h>
|
||||
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
# include <tbb/blocked_range.h>
|
||||
# include <tbb/parallel_for.h>
|
||||
# include <tbb/parallel_do.h>
|
||||
# include <tbb/cache_aligned_allocator.h>
|
||||
#endif
|
||||
|
||||
//#define TEST_CCSS
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
struct Sequential_with_forward_access_tag : public CGAL::Sequential_tag {};
|
||||
struct Sequential_with_random_access_tag : public CGAL::Sequential_tag {};
|
||||
|
||||
struct Parallel_for_tag : public CGAL::Parallel_tag {};
|
||||
struct Parallel_do_tag : public CGAL::Parallel_tag {};
|
||||
|
||||
struct Truc
|
||||
{
|
||||
Truc(int v = 0) : value(v), /*value2(v), */p(NULL) {}
|
||||
void * for_compact_container() const { return p; }
|
||||
void * & for_compact_container() { return p; }
|
||||
|
||||
int value;
|
||||
int value2;
|
||||
void * p;
|
||||
};
|
||||
|
||||
|
||||
inline void compute_the_thing(int &thing)
|
||||
{
|
||||
thing = static_cast<int>(10.*sqrt(0.3 + thing*thing/1.5)/2.6);
|
||||
//thing = 10*thing;
|
||||
}
|
||||
|
||||
inline void compute_the_thing(Truc &thing)
|
||||
{
|
||||
thing.value2=thing.value;
|
||||
compute_the_thing(thing.value2);
|
||||
}
|
||||
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
template <typename Array_t>
|
||||
class Change_array_functor
|
||||
{
|
||||
public:
|
||||
Change_array_functor(Array_t &v)
|
||||
: m_v(v) {}
|
||||
|
||||
void operator() (const tbb::blocked_range<size_t>& r) const
|
||||
{
|
||||
for(size_t i = r.begin(); i != r.end(); i++ )
|
||||
if (m_v.is_used(i))
|
||||
compute_the_thing(m_v[i]);
|
||||
}
|
||||
|
||||
private:
|
||||
Array_t &m_v;
|
||||
};
|
||||
|
||||
template <>
|
||||
class Change_array_functor<std::vector<Truc> >
|
||||
{
|
||||
public:
|
||||
Change_array_functor(std::vector<Truc> &v)
|
||||
: m_v(v) {}
|
||||
|
||||
void operator() (const tbb::blocked_range<size_t>& r) const
|
||||
{
|
||||
for(size_t i = r.begin(); i != r.end(); i++ )
|
||||
compute_the_thing(m_v[i]);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Truc> &m_v;
|
||||
};
|
||||
|
||||
// Parallel_for
|
||||
// For vector only
|
||||
double change_array(std::vector<Truc> &v, Parallel_for_tag)
|
||||
{
|
||||
std::cout << "[Parallel] Using a tbb::parallel_for loop...";
|
||||
CGAL::Real_timer t;
|
||||
t.start();
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<std::size_t>(0, v.size()),
|
||||
Change_array_functor<std::vector<Truc> >(v)
|
||||
);
|
||||
t.stop();
|
||||
std::cout << " done in " << t.time() << " seconds." << std::endl;
|
||||
return t.time();
|
||||
}
|
||||
|
||||
// Parallel_for
|
||||
// For Compact_container only
|
||||
template <typename Array_t>
|
||||
double change_array(Array_t &v, Parallel_for_tag)
|
||||
{
|
||||
std::cout << "[Parallel] Using a tbb::parallel_for loop...";
|
||||
CGAL::Real_timer t;
|
||||
t.start();
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<std::size_t>(0, v.capacity()),
|
||||
Change_array_functor<Array_t>(v)
|
||||
);
|
||||
t.stop();
|
||||
std::cout << " done in " << t.time() << " seconds." << std::endl;
|
||||
return t.time();
|
||||
}
|
||||
|
||||
// Parallel_do
|
||||
// For vector and Compact_container
|
||||
template <typename Array_t>
|
||||
double change_array(Array_t &v, Parallel_do_tag)
|
||||
{
|
||||
std::cout << "[Parallel] Using a tbb::parallel_do loop...";
|
||||
CGAL::Real_timer t;
|
||||
t.start();
|
||||
tbb::parallel_do(
|
||||
v.begin(), v.end(),
|
||||
[]( typename Array_t::value_type& truc ) // CJTODO: lambdas ok?
|
||||
{
|
||||
compute_the_thing(truc);
|
||||
});
|
||||
t.stop();
|
||||
std::cout << " done in " << t.time() << " seconds." << std::endl;
|
||||
return t.time();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Forward access
|
||||
// For vector & Compact_container
|
||||
template <typename Array_t>
|
||||
double change_array(Array_t &v, Sequential_with_forward_access_tag)
|
||||
{
|
||||
std::cout << "[Sequential] Using a sequential for loop (forward access)...";
|
||||
CGAL::Real_timer t;
|
||||
t.start();
|
||||
typename Array_t::iterator it = v.begin(), it_end = v.end();
|
||||
|
||||
for ( ; it != it_end ; ++it)
|
||||
compute_the_thing(*it);
|
||||
|
||||
t.stop();
|
||||
std::cout << " done in " << t.time() << " seconds." << std::endl;
|
||||
return t.time();
|
||||
}
|
||||
|
||||
// Random access
|
||||
// For vector only
|
||||
double change_array(std::vector<Truc> &v, Sequential_with_random_access_tag)
|
||||
{
|
||||
std::cout << "[Sequential] Using a sequential for loop (random access)...";
|
||||
CGAL::Real_timer t;
|
||||
t.start();
|
||||
std::vector<Truc>::iterator it = v.begin(), it_end = v.end();
|
||||
|
||||
for (int i = 0 ; i < v.size() ; ++i)
|
||||
compute_the_thing(v[i]);
|
||||
|
||||
t.stop();
|
||||
std::cout << " done in " << t.time() << " seconds." << std::endl;
|
||||
return t.time();
|
||||
}
|
||||
|
||||
// Random access
|
||||
// For Compact_container (use of "is_used")
|
||||
template <typename Array_t>
|
||||
double change_array(Array_t &v, Sequential_with_random_access_tag)
|
||||
{
|
||||
std::cout << "[Sequential] Using a sequential for loop (random access)...";
|
||||
CGAL::Real_timer t;
|
||||
t.start();
|
||||
for (int i = 0 ; i < v.capacity() ; ++i)
|
||||
{
|
||||
if (v.is_used(i))
|
||||
compute_the_thing(v[i]);
|
||||
}
|
||||
t.stop();
|
||||
std::cout << " done in " << t.time() << " seconds." << std::endl;
|
||||
return t.time();
|
||||
}
|
||||
|
||||
|
||||
template <typename Array_t>
|
||||
void benchmark(Array_t &v)
|
||||
{
|
||||
std::cout << "* Sequential algorithm (random access) => ";
|
||||
double seq_time_random = change_array(v, Sequential_with_random_access_tag());
|
||||
std::cout << "* Parallel_for algorithm => ";
|
||||
double parallel_for_time = change_array(v, Parallel_for_tag());
|
||||
std::cout << "Speed-up parallel_for (operator[]) = "
|
||||
<< seq_time_random/parallel_for_time << std::endl << std::endl;
|
||||
|
||||
std::cout << "* Sequential algorithm (forward access) => ";
|
||||
double seq_time_fw = change_array(v, Sequential_with_forward_access_tag());
|
||||
std::cout << "* Parallel_do algorithm => ";
|
||||
double parallel_do_time = change_array(v, Parallel_do_tag());
|
||||
std::cout << "Speed-up parallel_do (iterators) = "
|
||||
<< seq_time_fw/parallel_do_time << std::endl << std::endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
const int NUM_THINGS = 1000;
|
||||
#else
|
||||
const int NUM_THINGS = 10000000;
|
||||
#endif
|
||||
|
||||
std::cout << std::endl << "*** VECTOR ***" << std::endl;
|
||||
CGAL::Real_timer t;
|
||||
t.start();
|
||||
std::vector<Truc> v;
|
||||
for (int i = 0 ; i < NUM_THINGS ; ++i)
|
||||
v.push_back(i);
|
||||
t.stop();
|
||||
std::cout << "vector created in " << t.time() << " seconds." << std::endl;
|
||||
benchmark(v);
|
||||
|
||||
std::cout << std::endl << "*** CC<Addition> ***" << std::endl;
|
||||
t.reset();
|
||||
t.start();
|
||||
CGAL::Compact_container<Truc> v2;
|
||||
for (int i = 0 ; i < NUM_THINGS ; ++i)
|
||||
v2.emplace(i);
|
||||
t.stop();
|
||||
std::cout << "Compact_container created in " << t.time() << " seconds. Capacity = " << v2.capacity() << std::endl;
|
||||
benchmark(v2);
|
||||
|
||||
std::cout << std::endl << "*** CC<Constant> ***" << std::endl;
|
||||
t.reset();
|
||||
t.start();
|
||||
CGAL::Compact_container<Truc, CGAL::Default, CGAL::Constant_size_policy<1024> > v3;
|
||||
for (int i = 0 ; i < NUM_THINGS ; ++i)
|
||||
v3.emplace(i);
|
||||
t.stop();
|
||||
std::cout << "Compact_container<Constant_size_policy> created in " << t.time() << " seconds. Capacity = " << v3.capacity() << std::endl;
|
||||
benchmark(v3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue