From dbe23f23c65a0d4109cf53f4e2f62955cdea9f5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Jamin?= Date: Thu, 15 Mar 2012 15:11:42 +0000 Subject: [PATCH] For Concurrent_compact_container testing. --- .gitattributes | 1 + Mesh_3/test/Mesh_3/XML_exporter.h | 89 +++++++++ .../test_concurrent_compact_container.cpp | 186 +++++++++++++----- 3 files changed, 227 insertions(+), 49 deletions(-) create mode 100644 Mesh_3/test/Mesh_3/XML_exporter.h diff --git a/.gitattributes b/.gitattributes index a2d1aaf0e65..a25b228c5b6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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/maintainer -text 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/liver.inr.gz -text Mesh_3/test/Mesh_3/data/sphere.off -text svneol=unset#application/octet-stream diff --git a/Mesh_3/test/Mesh_3/XML_exporter.h b/Mesh_3/test/Mesh_3/XML_exporter.h new file mode 100644 index 00000000000..79781c32960 --- /dev/null +++ b/Mesh_3/test/Mesh_3/XML_exporter.h @@ -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 +#include +#include +#include + +template +class Simple_XML_exporter +{ + typedef std::vector Element; + typedef std::vector List_of_elements; + +public: + Simple_XML_exporter( const std::string &list_name, + const std::string &element_name, + const std::vector &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 << "" << 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::const_iterator it_subelement_name = m_subelement_names.begin(); + std::vector::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] + << " " << std::endl; + } + xmlfile << " " << std::endl; + } + + xmlfile << "" << std::endl; + xmlfile.close(); + return 0; + + } + +protected: + std::string m_list_name; + std::string m_element_name; + std::vector m_subelement_names; + List_of_elements m_list_of_elements; +}; diff --git a/Mesh_3/test/Mesh_3/test_concurrent_compact_container.cpp b/Mesh_3/test/Mesh_3/test_concurrent_compact_container.cpp index d14528081a1..820e9306dcb 100644 --- a/Mesh_3/test/Mesh_3/test_concurrent_compact_container.cpp +++ b/Mesh_3/test/Mesh_3/test_concurrent_compact_container.cpp @@ -18,16 +18,90 @@ // Author(s) : Clement Jamin #include -#include +#include "XML_exporter.h" +//#include //#include #include +#include + +#include +/* +// AN ATTEMPT TO REPRODUCE THE C1060 ERROR => COULDN'T DO IT +#include +#include + +#include +#include + +#include #include +namespace CGAL +{ +template , + class Cb = Triangulation_ds_cell_base_3<> > +class Mesh_complex_3_in_triangulation_3 +{ +public: + typedef Triangulation_data_structure_3 Tds; + typedef typename Vb::template Rebind_TDS::Other Vertex; + typedef typename Cb::template Rebind_TDS::Other Cell; -const size_t NUM_ITERATIONS = 20000000; + typedef Concurrent_compact_container 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, + boost::bimaps::multiset_of, + boost::bimaps::set_of_relation<>, + boost::bimaps::with_info > 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 m; + return 0; +}*/ + +#ifdef _DEBUG + const size_t NUM_ITERATIONS = 2000000; +#else + const size_t NUM_ITERATIONS = 200000000; +#endif using namespace CGAL; @@ -42,70 +116,84 @@ struct T void * & for_compact_container() { return (void*&)p; } }; -//typedef Compact_container Conc_container; -typedef Concurrent_compact_container Conc_container; + +template +void testContainer(const char *containerTypeName) +{ + std::cerr << "== " << containerTypeName << " ==" << std::endl; + std::cerr << "* Iterator size = " << sizeof(Container::iterator) << std::endl; + + std::vector subelements; + subelements.push_back("NumThreads"); + subelements.push_back("EraseRatio"); + subelements.push_back("Time"); + Simple_XML_exporter xml("ContainerPerformance", "Perf", subelements); + + 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); + Container ccc; + + WallClockTimer t2; + tbb::parallel_for(tbb::blocked_range(0, NUM_ITERATIONS), + [&]( const tbb::blocked_range& r ) { // CJTODO: lambdas ok? + for( size_t i = r.begin() ; i != r.end() ; ++i) + { + Container::iterator it = ccc.emplace(rand()); + if (rand() % 10 < erase_ratio) + { + ccc.erase(it); + } + } + }); + std::vector value; + value.push_back( num_threads ); + value.push_back( erase_ratio ); + value.push_back( static_cast(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; + } + } + + xml.export_to_xml(std::string("C:\\INRIA\\Reports\\CGAL\\Concurrent_compact_container\\") + containerTypeName + ".xml"); +} + +typedef Concurrent_compact_container Conc_container_CCbased; +typedef Concurrent_compact_container_TBB_based Conc_container_TBBbased; int main() { + // PERFORMANCE TEST + testContainer("Concurrent_compact_container - CC based"); + testContainer("Concurrent_compact_container - TBB based"); + /* std::cerr << "== Compact_container == Iterator size: " << sizeof(Compact_container::iterator) << std::endl; Compact_container cc; WallClockTimer t1; for( size_t i = 0 ; i != NUM_ITERATIONS ; ++i) { - std::vector::iterator> listOfIts; - if (listOfIts.empty()) + Compact_container::iterator it = cc.emplace(rand()); + if (rand() % 10 < 7) { - Compact_container::iterator it = cc.emplace(rand()); - if (rand() % 10 < 7) - listOfIts.push_back(it); - } - else - { - cc.erase(listOfIts.back()); - listOfIts.pop_back(); + cc.erase(it); } } - std::cerr << t1.elapsed() << " seconds." << std::endl; + 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) - { - tbb::task_scheduler_init init(num_threads); - Conc_container ccc; - - WallClockTimer t2; - tbb::parallel_for(tbb::blocked_range(0, NUM_ITERATIONS), - [&]( const tbb::blocked_range& r ) { // CJTODO: lambdas ok? - for( size_t i = r.begin() ; i != r.end() ; ++i) - { - std::vector listOfIts; - if (listOfIts.empty()) - { - Conc_container::iterator it = ccc.emplace(rand()); - 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; - } - - /*ccc.emplace(12); - Concurrent_compact_container::iterator it2 = ccc.emplace(1); + /*Conc_container ccc; + ccc.emplace(12); + Conc_container::iterator it2 = ccc.emplace(1); ccc.erase(it2); ccc.emplace(13); ccc.emplace(13); - Concurrent_compact_container::const_iterator it = ccc.begin(); - Concurrent_compact_container::const_iterator it_end = ccc.end(); + Conc_container::const_iterator it = ccc.begin(); + Conc_container::const_iterator it_end = ccc.end(); for( ; it != it_end ; ++it) - std::cerr << it->i << " " << std::endl; -*/ + std::cerr << it->i << " " << std::endl;*/ + return 0; }