You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
concurrentqueue/benchmarks/tbb/tbb_statistics.h

241 lines
9.4 KiB
C++

/*
Copyright 2005-2014 Intel Corporation. All Rights Reserved.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/
#ifndef _TBB_tbb_statistics_H
#define _TBB_tbb_statistics_H
/**
This file defines parameters of the internal statistics collected by the TBB
library (currently by the task scheduler only).
Statistics is accumulated separately in each thread and is dumped when
the scheduler instance associated with the given thread is destroyed.
For apps with multiple master threads or with the same master repeatedly
initializing and then deinitializing task scheduler this results in TBB
workers statistics getting inseparably mixed.
Therefore statistics is accumulated in arena slots, and should be dumped
when arena is destroyed. This separates statistics collected for each
scheduler activity region in each master thread.
With the current RML implementation (TBB 2.2, 3.0) to avoid complete loss of
statistics data during app shutdown (because of lazy workers deinitialization
logic) set __TBB_STATISTICS_EARLY_DUMP macro to write the statistics at the
moment a master thread deinitializes its scheduler. This may happen a little
earlier than the moment of arena destruction resulting in the following undesired
(though usually tolerable) effects:
- a few events related to unsuccessful stealing or thread pool activity may be lost,
- statistics may be substantially incomplete in case of FIFO tasks used in
the FAF mode.
Macro __TBB_STATISTICS_STDOUT and global variable __TBB_ActiveStatisticsGroups
defined below can be used to configure the statistics output.
To add new counter:
1) Insert it into the appropriate group range in statistics_counters;
2) Insert the corresponding field title into StatFieldTitles (preserving
relative order of the fields).
To add new counters group:
1) Insert new group bit flag into statistics_groups;
2) Insert the new group title into StatGroupTitles (preserving
relative order of the groups).
3) Add counter belonging to the new group as described above
**/
#include "tbb/tbb_stddef.h"
#ifndef __TBB_STATISTICS
#define __TBB_STATISTICS 0
#endif /* __TBB_STATISTICS */
#if __TBB_STATISTICS
#include <string.h> // for memset
//! Dump counters into stdout as well.
/** By default statistics counters are written to the file "statistics.txt" only. **/
#define __TBB_STATISTICS_STDOUT 1
//! Dump only totals for all threads in the given arena
/** By default statistics counters for each arena slot are dumped separately, as
well as the subtotal for workers. **/
#define __TBB_STATISTICS_TOTALS_ONLY 1
//! Dump statistics for an arena when its master completes
/** By default (when this macro is not set) the statistics is sent to output when
arena object is destroyed. But with the current lazy workers termination
logic default behavior may result in loosing all statistics output. **/
#define __TBB_STATISTICS_EARLY_DUMP 1
#define GATHER_STATISTIC(x) (x)
namespace tbb {
namespace internal {
//! Groups of statistics counters.
/** The order of enumerators must be the same as the order of the corresponding
field groups in the statistics_counters structure. **/
enum statistics_groups {
sg_task_allocation = 0x01,
sg_task_execution = 0x02,
sg_stealing = 0x04,
sg_affinity = 0x08,
sg_arena = 0x10,
sg_market = 0x20,
sg_prio = 0x40,
sg_prio_ex = 0x80,
// List end marker. Insert new groups only before it.
sg_end
};
//! Groups of counters to output
const uintptr_t __TBB_ActiveStatisticsGroups = sg_task_execution | sg_stealing | sg_affinity | sg_arena | sg_market;
//! A set of various statistics counters that are updated by the library on per thread basis.
/** All the fields must be of the same type (statistics_counters::counter_type).
This is necessary to allow reinterpreting this structure as an array. **/
struct statistics_counters {
typedef long counter_type;
// Group: sg_task_allocation
// Counters in this group can have negative values as the tasks migrate across
// threads while the associated counters are updated in the current thread only
// to avoid data races
//! Number of tasks allocated and not yet destroyed
counter_type active_tasks;
//! Number of task corpses stored for future reuse
counter_type free_list_length;
//! Number of big tasks allocated during the run
/** To find total number of tasks malloc'd, compute (big_tasks+my_small_task_count) */
counter_type big_tasks;
// Group: sg_task_execution
//! Number of tasks executed
counter_type tasks_executed;
//! Number of elided spawns
counter_type spawns_bypassed;
// Group: sg_stealing
//! Number of tasks successfully stolen
counter_type steals_committed;
//! Number of failed stealing attempts
counter_type steals_failed;
//! Number of failed attempts to lock victim's task pool
counter_type thieves_conflicts;
//! Number of times thief backed off because of the collision with the owner
counter_type thief_backoffs;
// Group: sg_affinity
//! Number of tasks received from mailbox
counter_type mails_received;
//! Number of affinitized tasks executed by the owner
/** Goes as "revoked" in statistics printout. **/
counter_type proxies_executed;
//! Number of affinitized tasks intercepted by thieves
counter_type proxies_stolen;
//! Number of proxy bypasses by thieves during stealing
counter_type proxies_bypassed;
//! Number of affinitized tasks executed by the owner via scheduler bypass mechanism
counter_type affinity_ignored;
// Group: sg_arena
//! Number of times the state of arena switched between "full" and "empty"
counter_type gate_switches;
//! Number of times workers left an arena and returned into the market
counter_type arena_roundtrips;
// !Average concurrency level of this arena
counter_type avg_arena_concurrency;
//! Average assigned priority
counter_type avg_assigned_workers;
// Group: sg_market
//! Number of times workers left the market and returned into RML
counter_type market_roundtrips;
// Group; sg_prio
//! Number of arena priority switches
counter_type arena_prio_switches;
//! Number of market priority switches
counter_type market_prio_switches;
//! Number of arena priority switches
counter_type arena_prio_resets;
//! Number of reference priority source fixups to avoid deadlock
counter_type prio_ref_fixups;
//! Average arena priority
counter_type avg_arena_prio;
//! Average market priority
counter_type avg_market_prio;
// Group; sg_prio_ex
//! Number of times local task pools were winnowed
counter_type prio_winnowings;
//! Number of times secondary task pools were searched for top priority tasks
counter_type prio_reloads;
//! Number of times secondary task pools were abandoned by quitting workers
counter_type prio_orphanings;
//! Number of tasks offloaded into secondary task pools
counter_type prio_tasks_offloaded;
//! Number of tasks reloaded from secondary task pools
counter_type prio_tasks_reloaded;
// Constructor and helpers
statistics_counters() { reset(); }
void reset () { memset( this, 0, sizeof(statistics_counters) ); }
counter_type& field ( size_t index ) { return reinterpret_cast<counter_type*>(this)[index]; }
const counter_type& field ( size_t index ) const { return reinterpret_cast<const counter_type*>(this)[index]; }
static size_t size () { return sizeof(statistics_counters) / sizeof(counter_type); }
const statistics_counters& operator += ( const statistics_counters& rhs ) {
for ( size_t i = 0; i < size(); ++i )
field(i) += rhs.field(i);
return *this;
}
}; // statistics_counters
static const size_t workers_counters_total = (size_t)-1;
static const size_t arena_counters_total = (size_t)-2;
void dump_statistics ( const statistics_counters& c, size_t id );
} // namespace internal
} // namespace tbb
#else /* !__TBB_STATISTICS */
#define GATHER_STATISTIC(x) ((void)0)
#endif /* !__TBB_STATISTICS */
#endif /* _TBB_tbb_statistics_H */