mirror of https://github.com/CGAL/cgal
For Concurrent_compact_container testing.
This commit is contained in:
parent
d56d031aa7
commit
dbe23f23c6
|
|
@ -2710,6 +2710,7 @@ Mesh_3/package_info/Mesh_3/description.txt -text
|
||||||
Mesh_3/package_info/Mesh_3/long_description.txt -text
|
Mesh_3/package_info/Mesh_3/long_description.txt -text
|
||||||
Mesh_3/package_info/Mesh_3/maintainer -text
|
Mesh_3/package_info/Mesh_3/maintainer -text
|
||||||
Mesh_3/stylesheet.css svneol=native#text/css
|
Mesh_3/stylesheet.css svneol=native#text/css
|
||||||
|
Mesh_3/test/Mesh_3/XML_exporter.h -text
|
||||||
Mesh_3/test/Mesh_3/data/cube.off -text svneol=unset#application/octet-stream
|
Mesh_3/test/Mesh_3/data/cube.off -text svneol=unset#application/octet-stream
|
||||||
Mesh_3/test/Mesh_3/data/liver.inr.gz -text
|
Mesh_3/test/Mesh_3/data/liver.inr.gz -text
|
||||||
Mesh_3/test/Mesh_3/data/sphere.off -text svneol=unset#application/octet-stream
|
Mesh_3/test/Mesh_3/data/sphere.off -text svneol=unset#application/octet-stream
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
// Copyright (c) 2012 INRIA Sophia-Antipolis (France).
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org).
|
||||||
|
// You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
// General Public License as published by the Free Software Foundation,
|
||||||
|
// either version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Licensees holding a valid commercial license may use this file in
|
||||||
|
// accordance with the commercial license agreement provided with the software.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// $URL: $
|
||||||
|
// $Id: $
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Clement Jamin
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
template<typename value_type = std::string>
|
||||||
|
class Simple_XML_exporter
|
||||||
|
{
|
||||||
|
typedef std::vector<value_type> Element;
|
||||||
|
typedef std::vector<Element> List_of_elements;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Simple_XML_exporter( const std::string &list_name,
|
||||||
|
const std::string &element_name,
|
||||||
|
const std::vector<std::string> &subelement_names )
|
||||||
|
: m_list_name(list_name), m_element_name(element_name),
|
||||||
|
m_subelement_names(subelement_names) {}
|
||||||
|
|
||||||
|
bool add_element(const Element &element)
|
||||||
|
{
|
||||||
|
if (element.size() == m_subelement_names.size())
|
||||||
|
{
|
||||||
|
m_list_of_elements.push_back(element);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: element.size() == m_subelement_names.size()" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool export_to_xml(const std::string &filename)
|
||||||
|
{
|
||||||
|
std::ofstream xmlfile;
|
||||||
|
xmlfile.open (filename);
|
||||||
|
xmlfile << "<?xml version='1.0'?>" << std::endl;
|
||||||
|
xmlfile << "<" << m_list_name << ">" << std::endl;
|
||||||
|
|
||||||
|
List_of_elements::const_iterator it_element = m_list_of_elements.begin();
|
||||||
|
List_of_elements::const_iterator it_element_end = m_list_of_elements.end();
|
||||||
|
for ( ; it_element != it_element_end ; ++it_element)
|
||||||
|
{
|
||||||
|
xmlfile << " <" << m_element_name << ">" << std::endl;
|
||||||
|
std::vector<std::string>::const_iterator it_subelement_name = m_subelement_names.begin();
|
||||||
|
std::vector<std::string>::const_iterator it_subelement_name_end = m_subelement_names.end();
|
||||||
|
for (int i = 0 ; it_subelement_name != it_subelement_name_end ; ++it_subelement_name, ++i)
|
||||||
|
{
|
||||||
|
xmlfile
|
||||||
|
<< " <" << *it_subelement_name << "> "
|
||||||
|
<< (*it_element)[i]
|
||||||
|
<< " </" << *it_subelement_name << ">" << std::endl;
|
||||||
|
}
|
||||||
|
xmlfile << " </" << m_element_name << ">" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlfile << "</" << m_list_name << ">" << std::endl;
|
||||||
|
xmlfile.close();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string m_list_name;
|
||||||
|
std::string m_element_name;
|
||||||
|
std::vector<std::string> m_subelement_names;
|
||||||
|
List_of_elements m_list_of_elements;
|
||||||
|
};
|
||||||
|
|
@ -18,16 +18,90 @@
|
||||||
// Author(s) : Clement Jamin
|
// Author(s) : Clement Jamin
|
||||||
|
|
||||||
#include <CGAL/Mesh_3/Profiling_tools.h>
|
#include <CGAL/Mesh_3/Profiling_tools.h>
|
||||||
#include <CGAL/Compact_container.h>
|
#include "XML_exporter.h"
|
||||||
|
//#include <CGAL/Compact_container.h>
|
||||||
//#include <CGAL/Compact_container - spion.h>
|
//#include <CGAL/Compact_container - spion.h>
|
||||||
#include <CGAL/Concurrent_compact_container.h>
|
#include <CGAL/Concurrent_compact_container.h>
|
||||||
|
#include <CGAL/Concurrent_compact_container - TBB based.h>
|
||||||
|
|
||||||
|
#include <tbb/tbb.h>
|
||||||
|
/*
|
||||||
|
// AN ATTEMPT TO REPRODUCE THE C1060 ERROR => COULDN'T DO IT
|
||||||
|
#include <CGAL/Triangulation_ds_vertex_base_3.h>
|
||||||
|
#include <CGAL/Triangulation_data_structure_3.h>
|
||||||
|
|
||||||
|
#include <boost/bimap/bimap.hpp>
|
||||||
|
#include <boost/bimap/multiset_of.hpp>
|
||||||
|
|
||||||
|
#include <libQGLViewer/libQ
|
||||||
|
|
||||||
#include <tbb/tbb.h>
|
#include <tbb/tbb.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace CGAL
|
||||||
|
{
|
||||||
|
template <typename Tr,
|
||||||
|
typename CornerIndex = int,
|
||||||
|
typename CurveSegmentIndex = int,
|
||||||
|
class Vb = Triangulation_ds_vertex_base_3<>,
|
||||||
|
class Cb = Triangulation_ds_cell_base_3<> >
|
||||||
|
class Mesh_complex_3_in_triangulation_3
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Triangulation_data_structure_3<Vb,Cb > Tds;
|
||||||
|
typedef typename Vb::template Rebind_TDS<Tds>::Other Vertex;
|
||||||
|
typedef typename Cb::template Rebind_TDS<Tds>::Other Cell;
|
||||||
|
|
||||||
const size_t NUM_ITERATIONS = 20000000;
|
typedef Concurrent_compact_container<Vertex> Vertex_range;
|
||||||
|
typedef typename Vertex_range::iterator Vertex_iterator;
|
||||||
|
typedef Vertex_iterator Vertex_handle;
|
||||||
|
|
||||||
|
|
||||||
|
typedef int CurveSegmentIndex;
|
||||||
|
typedef CurveSegmentIndex Curve_segment_index;
|
||||||
|
|
||||||
|
typedef boost::bimaps::bimap<
|
||||||
|
boost::bimaps::multiset_of<Vertex_handle>,
|
||||||
|
boost::bimaps::multiset_of<Vertex_handle>,
|
||||||
|
boost::bimaps::set_of_relation<>,
|
||||||
|
boost::bimaps::with_info<Curve_segment_index> > Edge_map;
|
||||||
|
|
||||||
|
typedef typename Edge_map::value_type Internal_edge;
|
||||||
|
|
||||||
|
|
||||||
|
Mesh_complex_3_in_triangulation_3()
|
||||||
|
: edges_()
|
||||||
|
{
|
||||||
|
Vertex_handle v1, v2;
|
||||||
|
Internal_edge e = make_internal_edge(v1, v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Internal_edge make_internal_edge(const Vertex_handle& v1,
|
||||||
|
const Vertex_handle& v2) const
|
||||||
|
{
|
||||||
|
if ( v1 < v2 ) { return Internal_edge(v1,v2); }
|
||||||
|
else { return Internal_edge(v2,v1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
Edge_map edges_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
CGAL::Mesh_complex_3_in_triangulation_3<int> m;
|
||||||
|
return 0;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
const size_t NUM_ITERATIONS = 2000000;
|
||||||
|
#else
|
||||||
|
const size_t NUM_ITERATIONS = 200000000;
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace CGAL;
|
using namespace CGAL;
|
||||||
|
|
||||||
|
|
@ -42,70 +116,84 @@ struct T
|
||||||
void * & for_compact_container() { return (void*&)p; }
|
void * & for_compact_container() { return (void*&)p; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//typedef Compact_container<T, CGAL_ALLOCATOR(T), CGAL::Parallel_tag> Conc_container;
|
|
||||||
typedef Concurrent_compact_container<T> Conc_container;
|
|
||||||
|
|
||||||
int main()
|
template <typename Container>
|
||||||
|
void testContainer(const char *containerTypeName)
|
||||||
{
|
{
|
||||||
std::cerr << "== Compact_container == Iterator size: " << sizeof(Compact_container<T>::iterator) << std::endl;
|
std::cerr << "== " << containerTypeName << " ==" << std::endl;
|
||||||
|
std::cerr << "* Iterator size = " << sizeof(Container::iterator) << std::endl;
|
||||||
|
|
||||||
Compact_container<T> cc;
|
std::vector<std::string> subelements;
|
||||||
WallClockTimer t1;
|
subelements.push_back("NumThreads");
|
||||||
for( size_t i = 0 ; i != NUM_ITERATIONS ; ++i)
|
subelements.push_back("EraseRatio");
|
||||||
{
|
subelements.push_back("Time");
|
||||||
std::vector<Compact_container<T>::iterator> listOfIts;
|
Simple_XML_exporter<int> xml("ContainerPerformance", "Perf", subelements);
|
||||||
if (listOfIts.empty())
|
|
||||||
{
|
|
||||||
Compact_container<T>::iterator it = cc.emplace(rand());
|
|
||||||
if (rand() % 10 < 7)
|
|
||||||
listOfIts.push_back(it);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cc.erase(listOfIts.back());
|
|
||||||
listOfIts.pop_back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cerr << t1.elapsed() << " seconds." << std::endl;
|
|
||||||
|
|
||||||
std::cerr << "== Concurrent_compact_container == Iterator size: " << sizeof(Conc_container::iterator) << std::endl;
|
|
||||||
for (int num_threads = 1 ; num_threads <= 8 ; ++num_threads)
|
for (int num_threads = 1 ; num_threads <= 8 ; ++num_threads)
|
||||||
|
{
|
||||||
|
for (int erase_ratio = 0 ; erase_ratio <= 10 ; ++erase_ratio)
|
||||||
{
|
{
|
||||||
tbb::task_scheduler_init init(num_threads);
|
tbb::task_scheduler_init init(num_threads);
|
||||||
Conc_container ccc;
|
Container ccc;
|
||||||
|
|
||||||
WallClockTimer t2;
|
WallClockTimer t2;
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, NUM_ITERATIONS),
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, NUM_ITERATIONS),
|
||||||
[&]( const tbb::blocked_range<size_t>& r ) { // CJTODO: lambdas ok?
|
[&]( const tbb::blocked_range<size_t>& r ) { // CJTODO: lambdas ok?
|
||||||
for( size_t i = r.begin() ; i != r.end() ; ++i)
|
for( size_t i = r.begin() ; i != r.end() ; ++i)
|
||||||
{
|
{
|
||||||
std::vector<Conc_container::iterator> listOfIts;
|
Container::iterator it = ccc.emplace(rand());
|
||||||
if (listOfIts.empty())
|
if (rand() % 10 < erase_ratio)
|
||||||
{
|
{
|
||||||
Conc_container::iterator it = ccc.emplace(rand());
|
ccc.erase(it);
|
||||||
if (rand() % 10 < 7)
|
|
||||||
listOfIts.push_back(it);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ccc.erase(listOfIts.back());
|
|
||||||
listOfIts.pop_back();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
std::cerr << "Num_threads=" << num_threads << ": " << t2.elapsed() << " seconds." << std::endl;
|
std::vector<int> value;
|
||||||
|
value.push_back( num_threads );
|
||||||
|
value.push_back( erase_ratio );
|
||||||
|
value.push_back( static_cast<int>(t2.elapsed()*1000) );
|
||||||
|
xml.add_element(value);
|
||||||
|
std::cerr << "Num_threads=" << num_threads << " / Erase_ratio=" << (float)erase_ratio/10.f << " => " << t2.elapsed() << " seconds." << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ccc.emplace(12);
|
xml.export_to_xml(std::string("C:\\INRIA\\Reports\\CGAL\\Concurrent_compact_container\\") + containerTypeName + ".xml");
|
||||||
Concurrent_compact_container<T>::iterator it2 = ccc.emplace(1);
|
}
|
||||||
|
|
||||||
|
typedef Concurrent_compact_container<T> Conc_container_CCbased;
|
||||||
|
typedef Concurrent_compact_container_TBB_based<T> Conc_container_TBBbased;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// PERFORMANCE TEST
|
||||||
|
testContainer<Conc_container_CCbased>("Concurrent_compact_container - CC based");
|
||||||
|
testContainer<Conc_container_TBBbased>("Concurrent_compact_container - TBB based");
|
||||||
|
/*
|
||||||
|
std::cerr << "== Compact_container == Iterator size: " << sizeof(Compact_container<T>::iterator) << std::endl;
|
||||||
|
|
||||||
|
Compact_container<T> cc;
|
||||||
|
WallClockTimer t1;
|
||||||
|
for( size_t i = 0 ; i != NUM_ITERATIONS ; ++i)
|
||||||
|
{
|
||||||
|
Compact_container<T>::iterator it = cc.emplace(rand());
|
||||||
|
if (rand() % 10 < 7)
|
||||||
|
{
|
||||||
|
cc.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cerr << t1.elapsed() << " seconds." << std::endl;*/
|
||||||
|
|
||||||
|
/*Conc_container ccc;
|
||||||
|
ccc.emplace(12);
|
||||||
|
Conc_container::iterator it2 = ccc.emplace(1);
|
||||||
ccc.erase(it2);
|
ccc.erase(it2);
|
||||||
ccc.emplace(13);
|
ccc.emplace(13);
|
||||||
ccc.emplace(13);
|
ccc.emplace(13);
|
||||||
|
|
||||||
Concurrent_compact_container<T>::const_iterator it = ccc.begin();
|
Conc_container::const_iterator it = ccc.begin();
|
||||||
Concurrent_compact_container<T>::const_iterator it_end = ccc.end();
|
Conc_container::const_iterator it_end = ccc.end();
|
||||||
for( ; it != it_end ; ++it)
|
for( ; it != it_end ; ++it)
|
||||||
std::cerr << it->i << " " << std::endl;
|
std::cerr << it->i << " " << std::endl;*/
|
||||||
*/
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue