dust3d/thirdparty/cgal/CGAL-5.1/include/CGAL/Profile_counter.h

255 lines
6.8 KiB
C
Raw Normal View History

//r Copyright (c) 2005,2006,2008 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
2020-10-13 12:44:25 +00:00
// This file is part of CGAL (www.cgal.org)
//
2020-10-13 12:44:25 +00:00
// $URL: https://github.com/CGAL/cgal/blob/v5.1/Profiling_tools/include/CGAL/Profile_counter.h $
// $Id: Profile_counter.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Sylvain Pion
#ifndef CGAL_PROFILE_COUNTER_H
#define CGAL_PROFILE_COUNTER_H
// This file contains several classes to help in profiling, together with macros
// triggered by CGAL_PROFILE to enable them:
//
// - Profile_counter which is able to keep track of a number, and prints a
// message in the destructor. Typically, it can be used as a profile counter
// in a static variable.
//
// - Profile_histogram_counter which is similar, but the counter is indexed by
// a value (unsigned int), and the final dump is the histogram of the non-zero
// counters.
//
// - Profile_branch_counter which keeps track of 2 counters, aiming at measuring
// the ratio corresponding to the number of times a branch is taken.
//
// - Profile_branch_counter_3 which keeps track of 3 counters, aiming at measuring
// the ratios corresponding to the number of times 2 branches are taken.
//
// If CGAL_CONCURRENT_PROFILE is defined, the counters can be concurrently updated
2020-10-13 12:44:25 +00:00
//
// See also CGAL/Profile_timer.h
// TODO :
// - Really complete the documentation!
// - Probably at some point we will need ways to selectively enable/disable profilers?
// (kind-wise and/or place-wise)
// - Ideas for new kinds of profilers:
// - lock counters in parallel mode
// (e.g. time spent spinning, and/or number of locks taken or forbidden...)
#include <CGAL/config.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
#include <map>
#include <CGAL/disable_warnings.h>
// Automatically define CGAL_CONCURRENT_PROFILE if we're linked with TBB
#ifdef CGAL_LINKED_WITH_TBB
# ifndef CGAL_CONCURRENT_PROFILE
# define CGAL_CONCURRENT_PROFILE
# endif
#else
// Automatically UNdefine CGAL_CONCURRENT_PROFILE if we're NOT linked with TBB
# ifdef CGAL_CONCURRENT_PROFILE
# undef CGAL_CONCURRENT_PROFILE
# endif
#endif
#ifdef CGAL_CONCURRENT_PROFILE
# include "tbb/concurrent_hash_map.h"
#endif
namespace CGAL {
namespace internal {
struct dotted : std::numpunct<char> {
char do_thousands_sep() const { return '.'; } // separate with dots
std::string do_grouping() const { return "\3"; } // groups of 3 digits
static void imbue(std::ostream &os) {
os.imbue(std::locale(os.getloc(), new dotted));
}
};
inline std::string dot_it(int i)
{
std::stringstream ss;
dotted::imbue(ss);
ss << i;
return ss.str();
}
}
struct Profile_counter
{
Profile_counter(const std::string & ss)
2020-10-13 12:44:25 +00:00
: s(ss)
{
2020-10-13 12:44:25 +00:00
i = 0; // needed here because of tbb::atomic
}
void operator++() { ++i; }
~Profile_counter()
{
2020-10-13 12:44:25 +00:00
std::cerr << "[CGAL::Profile_counter] "
<< std::setw(10) << internal::dot_it(i) << " " << s << std::endl;
}
private:
#ifdef CGAL_CONCURRENT_PROFILE
tbb::atomic<unsigned int> i;
#else
unsigned int i;
#endif
const std::string s;
};
struct Profile_histogram_counter
{
private:
#ifdef CGAL_CONCURRENT_PROFILE
typedef tbb::concurrent_hash_map<unsigned, unsigned> Counters;
#else
typedef std::map<unsigned, unsigned> Counters;
#endif
public:
Profile_histogram_counter(const std::string & ss)
: s(ss) {}
2020-10-13 12:44:25 +00:00
void operator()(unsigned i)
{
#ifdef CGAL_CONCURRENT_PROFILE
Counters::accessor a;
counters.insert(a, i);
++a->second;
#else
2020-10-13 12:44:25 +00:00
++counters[i];
#endif
}
~Profile_histogram_counter()
{
unsigned total=0;
for (Counters::const_iterator it=counters.begin(), end=counters.end();
it != end; ++it) {
std::cerr << "[CGAL::Profile_histogram_counter] " << s;
std::cerr << " [ " << std::setw(10) << internal::dot_it(it->first) << " : "
<< std::setw(10) << internal::dot_it(it->second) << " ]"
<< std::endl;
total += it->second;
}
std::cerr << "[CGAL::Profile_histogram_counter] " << s;
std::cerr << " [ " << std::setw(10) << "Total" << " : "
<< std::setw(10) << total << " ]" << std::endl;
}
private:
Counters counters;
const std::string s;
};
struct Profile_branch_counter
{
Profile_branch_counter(const std::string & ss)
: s(ss)
{
2020-10-13 12:44:25 +00:00
i = j = 0; // needed here because of tbb::atomic
}
void operator++() { ++i; }
void increment_branch() { ++j; }
~Profile_branch_counter()
{
std::cerr << "[CGAL::Profile_branch_counter] "
<< std::setw(10) << internal::dot_it(j) << " / "
<< std::setw(10) << internal::dot_it(i) << " " << s << std::endl;
}
private:
#ifdef CGAL_CONCURRENT_PROFILE
tbb::atomic<unsigned int> i, j;
#else
unsigned int i, j;
#endif
const std::string s;
};
struct Profile_branch_counter_3
{
Profile_branch_counter_3(const std::string & ss)
2020-10-13 12:44:25 +00:00
: s(ss)
{
2020-10-13 12:44:25 +00:00
i = j = k = 0; // needed here because of tbb::atomic
}
void operator++() { ++i; }
void increment_branch_1() { ++j; }
void increment_branch_2() { ++k; }
~Profile_branch_counter_3()
{
std::cerr << "[CGAL::Profile_branch_counter_3] "
<< std::setw(10) << internal::dot_it(k) << " / "
<< std::setw(10) << internal::dot_it(j) << " / "
<< std::setw(10) << internal::dot_it(i) << " " << s << std::endl;
}
private:
#ifdef CGAL_CONCURRENT_PROFILE
tbb::atomic<unsigned int> i, j, k;
#else
unsigned int i, j, k;
#endif
const std::string s;
};
#ifdef CGAL_PROFILE
# define CGAL_PROFILER(Y) \
{ static CGAL::Profile_counter tmp(Y); ++tmp; }
# define CGAL_HISTOGRAM_PROFILER(Y, Z) \
{ static CGAL::Profile_histogram_counter tmp(Y); tmp(Z); }
# define CGAL_BRANCH_PROFILER(Y, NAME) \
static CGAL::Profile_branch_counter NAME(Y); ++NAME;
# define CGAL_BRANCH_PROFILER_BRANCH(NAME) \
NAME.increment_branch();
# define CGAL_BRANCH_PROFILER_3(Y, NAME) \
static CGAL::Profile_branch_counter_3 NAME(Y); ++NAME;
# define CGAL_BRANCH_PROFILER_BRANCH_1(NAME) \
NAME.increment_branch_1();
# define CGAL_BRANCH_PROFILER_BRANCH_2(NAME) \
NAME.increment_branch_2();
#else
# define CGAL_PROFILER(Y)
# define CGAL_HISTOGRAM_PROFILER(Y, Z)
# define CGAL_BRANCH_PROFILER(Y, NAME)
# define CGAL_BRANCH_PROFILER_BRANCH(NAME)
2020-10-13 12:44:25 +00:00
# define CGAL_BRANCH_PROFILER_3(Y, NAME)
# define CGAL_BRANCH_PROFILER_BRANCH_1(NAME)
2020-10-13 12:44:25 +00:00
# define CGAL_BRANCH_PROFILER_BRANCH_2(NAME)
#endif
} //namespace CGAL
#include <CGAL/enable_warnings.h>
#endif // CGAL_PROFILE_COUNTER_H