mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-24 04:50:34 +05:00
Merge branch 'parallel_timing' into 'master'
Thread-safe Timer See merge request jschoeberl/netgen!392
This commit is contained in:
commit
44d7207380
@ -85,8 +85,7 @@ namespace ngcore
|
||||
for(auto & ltask : tasks)
|
||||
for(auto & task : ltask)
|
||||
{
|
||||
task.start_time -= start_time;
|
||||
task.stop_time -= start_time;
|
||||
task.time -= start_time;
|
||||
}
|
||||
for(auto & job : jobs)
|
||||
{
|
||||
@ -635,23 +634,31 @@ namespace ngcore
|
||||
value_id = job_task_map[jobs[t.id-1].type];
|
||||
if(trace_thread_counter)
|
||||
{
|
||||
paje.AddVariable( t.start_time, variable_type_active_threads, container_jobs, 1.0 );
|
||||
paje.SubVariable( t.stop_time, variable_type_active_threads, container_jobs, 1.0 );
|
||||
if(t.is_start)
|
||||
paje.AddVariable( t.time, variable_type_active_threads, container_jobs, 1.0 );
|
||||
else
|
||||
paje.SubVariable( t.time, variable_type_active_threads, container_jobs, 1.0 );
|
||||
}
|
||||
if(trace_threads)
|
||||
{
|
||||
paje.PushState( t.start_time, state_type_task, thread_aliases[t.thread_id], value_id, t.additional_value, true );
|
||||
paje.PopState( t.stop_time, state_type_task, thread_aliases[t.thread_id] );
|
||||
if(t.is_start)
|
||||
paje.PushState( t.time, state_type_task, thread_aliases[t.thread_id], value_id, t.additional_value, true );
|
||||
else
|
||||
paje.PopState( t.time, state_type_task, thread_aliases[t.thread_id] );
|
||||
}
|
||||
break;
|
||||
case Task::ID_TIMER:
|
||||
value_id = timer_aliases[t.id];
|
||||
paje.PushState( t.start_time, state_type_timer, thread_aliases[t.thread_id], value_id, t.additional_value, true );
|
||||
paje.PopState( t.stop_time, state_type_timer, thread_aliases[t.thread_id] );
|
||||
if(t.is_start)
|
||||
paje.PushState( t.time, state_type_timer, thread_aliases[t.thread_id], value_id, t.additional_value, true );
|
||||
else
|
||||
paje.PopState( t.time, state_type_timer, thread_aliases[t.thread_id] );
|
||||
break;
|
||||
default:
|
||||
paje.PushState( t.start_time, state_type_task, thread_aliases[t.thread_id], value_id, t.additional_value, false );
|
||||
paje.PopState( t.stop_time, state_type_task, thread_aliases[t.thread_id] );
|
||||
if(t.is_start)
|
||||
paje.PushState( t.time, state_type_task, thread_aliases[t.thread_id], value_id, t.additional_value, false );
|
||||
else
|
||||
paje.PopState( t.time, state_type_task, thread_aliases[t.thread_id] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -79,8 +79,8 @@ namespace ngcore
|
||||
|
||||
int additional_value;
|
||||
|
||||
TTimePoint start_time;
|
||||
TTimePoint stop_time;
|
||||
TTimePoint time;
|
||||
bool is_start;
|
||||
|
||||
static constexpr int ID_NONE = -1;
|
||||
static constexpr int ID_JOB = 1;
|
||||
@ -178,23 +178,16 @@ namespace ngcore
|
||||
if(unlikely(tasks[thread_id].size() == max_num_events_per_thread))
|
||||
StopTracing();
|
||||
int task_num = tasks[thread_id].size();
|
||||
tasks[thread_id].push_back( Task{thread_id, id, id_type, additional_value, GetTimeCounter()} );
|
||||
tasks[thread_id].push_back( Task{thread_id, id, id_type, additional_value, GetTimeCounter(), true} );
|
||||
return task_num;
|
||||
}
|
||||
|
||||
void StopTask(int thread_id, int task_num)
|
||||
void StopTask(int thread_id, int id, int id_type = Task::ID_NONE)
|
||||
{
|
||||
if(!trace_threads && !trace_thread_counter) return;
|
||||
if(task_num>=0)
|
||||
tasks[thread_id][task_num].stop_time = GetTimeCounter();
|
||||
tasks[thread_id].push_back( Task{thread_id, id, id_type, 0, GetTimeCounter(), false} );
|
||||
}
|
||||
|
||||
void SetTask(int thread_id, int task_num, int additional_value) {
|
||||
if(!trace_threads && !trace_thread_counter) return;
|
||||
if(task_num>=0)
|
||||
tasks[thread_id][task_num].additional_value = additional_value;
|
||||
}
|
||||
|
||||
void StartJob(int job_id, const std::type_info & type)
|
||||
{
|
||||
if(!tracing_enabled) return;
|
||||
|
@ -148,38 +148,95 @@ namespace ngcore
|
||||
};
|
||||
|
||||
|
||||
struct TNoTracing{ static constexpr bool do_tracing=false; };
|
||||
struct TTracing{ static constexpr bool do_tracing=true; };
|
||||
|
||||
class NGCORE_API Timer
|
||||
struct TNoTiming{ static constexpr bool do_timing=false; };
|
||||
struct TTiming{ static constexpr bool do_timing=true; };
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
constexpr bool is_tracing_type_v = std::is_same_v<T, TNoTracing> || std::is_same_v<T, TTracing>;
|
||||
|
||||
template<typename T>
|
||||
constexpr bool is_timing_type_v = std::is_same_v<T, TNoTiming> || std::is_same_v<T, TTiming>;
|
||||
}
|
||||
|
||||
static TNoTracing NoTracing;
|
||||
static TNoTiming NoTiming;
|
||||
|
||||
template<typename TTracing=TTracing, typename TTiming=TTiming>
|
||||
class Timer
|
||||
{
|
||||
int timernr;
|
||||
int priority;
|
||||
public:
|
||||
Timer (const std::string & name, int apriority = 1)
|
||||
: priority(apriority)
|
||||
int Init( const std::string & name )
|
||||
{
|
||||
timernr = NgProfiler::CreateTimer (name);
|
||||
return NgProfiler::CreateTimer (name);
|
||||
}
|
||||
public:
|
||||
static constexpr bool do_tracing = TTracing::do_tracing;
|
||||
static constexpr bool do_timing = TTiming::do_timing;
|
||||
|
||||
Timer (const std::string & name) : timernr(Init(name)) { }
|
||||
|
||||
template<std::enable_if_t< detail::is_tracing_type_v<TTracing>, bool> = false>
|
||||
Timer( const std::string & name, TTracing ) : timernr(Init(name)) { }
|
||||
|
||||
template<std::enable_if_t< detail::is_timing_type_v<TTiming>, bool> = false>
|
||||
Timer( const std::string & name, TTiming ) : timernr(Init(name)) { }
|
||||
|
||||
Timer( const std::string & name, TTracing, TTiming ) : timernr(Init(name)) { }
|
||||
|
||||
void SetName (const std::string & name)
|
||||
{
|
||||
NgProfiler::SetName (timernr, name);
|
||||
}
|
||||
void Start ()
|
||||
void Start () const
|
||||
{
|
||||
if (priority <= 2)
|
||||
NgProfiler::StartTimer (timernr);
|
||||
if (priority <= 1)
|
||||
if(trace) trace->StartTimer(timernr);
|
||||
Start(TaskManager::GetThreadId());
|
||||
}
|
||||
void Stop ()
|
||||
void Stop () const
|
||||
{
|
||||
if (priority <= 2)
|
||||
NgProfiler::StopTimer (timernr);
|
||||
if (priority <= 1)
|
||||
if(trace) trace->StopTimer(timernr);
|
||||
Stop(TaskManager::GetThreadId());
|
||||
}
|
||||
void Start (int tid) const
|
||||
{
|
||||
if(tid==0)
|
||||
{
|
||||
if constexpr(do_timing)
|
||||
NgProfiler::StartTimer (timernr);
|
||||
if constexpr(do_tracing)
|
||||
if(trace) trace->StartTimer(timernr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr(do_timing)
|
||||
NgProfiler::StartThreadTimer(timernr, tid);
|
||||
if constexpr(do_tracing)
|
||||
if(trace) trace->StartTask (tid, timernr, PajeTrace::Task::ID_TIMER);
|
||||
}
|
||||
}
|
||||
void Stop (int tid) const
|
||||
{
|
||||
if(tid==0)
|
||||
{
|
||||
if constexpr(do_timing)
|
||||
NgProfiler::StopTimer (timernr);
|
||||
if constexpr(do_tracing)
|
||||
if(trace) trace->StopTimer(timernr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr(do_timing)
|
||||
NgProfiler::StopThreadTimer(timernr, tid);
|
||||
if constexpr(do_tracing)
|
||||
if(trace) trace->StopTask (tid, timernr, PajeTrace::Task::ID_TIMER);
|
||||
}
|
||||
}
|
||||
void AddFlops (double aflops)
|
||||
{
|
||||
if (priority <= 2)
|
||||
if constexpr(do_timing)
|
||||
NgProfiler::AddFlops (timernr, aflops);
|
||||
}
|
||||
|
||||
@ -196,14 +253,21 @@ namespace ngcore
|
||||
Timer object.
|
||||
Start / stop timer at constructor / destructor.
|
||||
*/
|
||||
template<typename TTimer>
|
||||
class RegionTimer
|
||||
{
|
||||
Timer & timer;
|
||||
const TTimer & timer;
|
||||
int tid;
|
||||
public:
|
||||
/// start timer
|
||||
RegionTimer (Timer & atimer) : timer(atimer) { timer.Start(); }
|
||||
RegionTimer (const TTimer & atimer) : timer(atimer)
|
||||
{
|
||||
tid = TaskManager::GetThreadId();
|
||||
timer.Start(tid);
|
||||
}
|
||||
|
||||
/// stop timer
|
||||
~RegionTimer () { timer.Stop(); }
|
||||
~RegionTimer () { timer.Stop(tid); }
|
||||
|
||||
RegionTimer() = delete;
|
||||
RegionTimer(const RegionTimer &) = delete;
|
||||
@ -212,29 +276,11 @@ namespace ngcore
|
||||
void operator=(RegionTimer &&) = delete;
|
||||
};
|
||||
|
||||
class ThreadRegionTimer
|
||||
{
|
||||
size_t nr;
|
||||
size_t tid;
|
||||
public:
|
||||
/// start timer
|
||||
ThreadRegionTimer (size_t _nr, size_t _tid) : nr(_nr), tid(_tid)
|
||||
{ NgProfiler::StartThreadTimer(nr, tid); }
|
||||
/// stop timer
|
||||
~ThreadRegionTimer ()
|
||||
{ NgProfiler::StopThreadTimer(nr, tid); }
|
||||
|
||||
ThreadRegionTimer() = delete;
|
||||
ThreadRegionTimer(ThreadRegionTimer &&) = delete;
|
||||
ThreadRegionTimer(const ThreadRegionTimer &) = delete;
|
||||
void operator=(const ThreadRegionTimer &) = delete;
|
||||
void operator=(ThreadRegionTimer &&) = delete;
|
||||
};
|
||||
|
||||
class RegionTracer
|
||||
{
|
||||
int nr;
|
||||
int thread_id;
|
||||
int type;
|
||||
public:
|
||||
static constexpr int ID_JOB = PajeTrace::Task::ID_JOB;
|
||||
static constexpr int ID_NONE = PajeTrace::Task::ID_NONE;
|
||||
@ -251,28 +297,26 @@ namespace ngcore
|
||||
: thread_id(athread_id)
|
||||
{
|
||||
if (trace)
|
||||
nr = trace->StartTask (athread_id, region_id, id_type, additional_value);
|
||||
trace->StartTask (athread_id, region_id, id_type, additional_value);
|
||||
type = id_type;
|
||||
nr = region_id;
|
||||
}
|
||||
/// start trace with timer
|
||||
RegionTracer (int athread_id, Timer & timer, int additional_value = -1 )
|
||||
template<typename TTimer>
|
||||
RegionTracer (int athread_id, TTimer & timer, int additional_value = -1 )
|
||||
: thread_id(athread_id)
|
||||
{
|
||||
nr = timer;
|
||||
type = ID_TIMER;
|
||||
if (trace)
|
||||
nr = trace->StartTask (athread_id, static_cast<int>(timer), ID_TIMER, additional_value);
|
||||
trace->StartTask (athread_id, nr, type, additional_value);
|
||||
}
|
||||
|
||||
/// set user defined value
|
||||
void SetValue( int additional_value )
|
||||
{
|
||||
if (trace)
|
||||
trace->SetTask( thread_id, nr, additional_value );
|
||||
}
|
||||
|
||||
/// stop trace
|
||||
~RegionTracer ()
|
||||
{
|
||||
if (trace)
|
||||
trace->StopTask (thread_id, nr);
|
||||
trace->StopTask (thread_id, nr, type);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -35,11 +35,7 @@ namespace ngcore
|
||||
int TaskManager :: num_threads = 1;
|
||||
|
||||
|
||||
// #ifndef __clang__
|
||||
thread_local int TaskManager :: thread_id = 0;
|
||||
// #else
|
||||
// __thread int TaskManager :: thread_id;
|
||||
// #endif
|
||||
|
||||
const function<void(TaskInfo&)> * TaskManager::func;
|
||||
const function<void()> * TaskManager::startup_function = nullptr;
|
||||
@ -174,10 +170,12 @@ namespace ngcore
|
||||
num_threads = 1;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
int TaskManager :: GetThreadId()
|
||||
{
|
||||
return thread_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
void TaskManager :: StartWorkers()
|
||||
{
|
||||
|
@ -78,12 +78,11 @@ namespace ngcore
|
||||
|
||||
|
||||
|
||||
// #ifndef __clang__
|
||||
#ifdef WIN32 // no exported thread_local in dlls on Windows
|
||||
static thread_local int thread_id;
|
||||
// #else
|
||||
// static __thread int thread_id;
|
||||
// #endif
|
||||
|
||||
#else
|
||||
NGCORE_API static thread_local int thread_id;
|
||||
#endif
|
||||
NGCORE_API static bool use_paje_trace;
|
||||
public:
|
||||
|
||||
@ -102,11 +101,15 @@ namespace ngcore
|
||||
void ResumeWorkers() { sleep = false; }
|
||||
|
||||
NGCORE_API static void SetNumThreads(int amax_threads);
|
||||
NGCORE_API static int GetMaxThreads() { return max_threads; }
|
||||
static int GetMaxThreads() { return max_threads; }
|
||||
// static int GetNumThreads() { return task_manager ? task_manager->num_threads : 1; }
|
||||
NGCORE_API static int GetNumThreads() { return num_threads; }
|
||||
static int GetNumThreads() { return num_threads; }
|
||||
#ifdef WIN32
|
||||
NGCORE_API static int GetThreadId();
|
||||
NGCORE_API int GetNumNodes() const { return num_nodes; }
|
||||
#else
|
||||
static int GetThreadId() { return thread_id; }
|
||||
#endif
|
||||
int GetNumNodes() const { return num_nodes; }
|
||||
|
||||
static void SetPajeTrace (bool use) { use_paje_trace = use; }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user