コード例 #1
0
ファイル: taskmanager.cpp プロジェクト: ddrake/ngsolve
  TaskManager :: TaskManager()
    {
      num_threads = GetMaxThreads();
      // if (MyMPI_GetNTasks() > 1) num_threads = 1;

#ifdef USE_NUMA
      numa_available();
      num_nodes = numa_max_node() + 1;
      if (num_nodes > num_threads) num_nodes = num_threads;

      for (int j = 0; j < num_nodes; j++)
        {
          void * mem = numa_alloc_onnode (sizeof(NodeData), j);
          nodedata[j] = new (mem) NodeData;
	  complete[j] = -1;
          workers_on_node[j] = 0;          
        }
#else
      num_nodes = 1;
      nodedata[0] = new NodeData;
      complete[0] = -1;
      workers_on_node[0] = 0;
#endif

      jobnr = 0;
      done = 0;
      sleep = false;
      sleep_usecs = 1000;
      active_workers = 0;

      static int cnt = 0;
      char buf[100];
      if (use_paje_trace)
        {
#ifdef PARALLEL
          sprintf(buf, "ng%d_rank%d.trace", cnt++, MyMPI_GetId());
#else
          sprintf(buf, "ng%d.trace", cnt++);
#endif
        }
      else
        buf[0] = 0;
      //sprintf(buf, "");
      trace = new PajeTrace(num_threads, buf);
    }
コード例 #2
0
CTimeSpan
CThreadPool_Controller_PID::GetSafeSleepTime(void) const
{
    double last_err = 0, integr_err = 0;
    CThreadPool* pool = GetPool();
    if (!pool) {
        return CTimeSpan(0, 0);
    }
    {{
        CMutexGuard guard(GetMainPoolMutex(pool));

        if (m_ErrHistory.size() == 0) {
            return CThreadPool_Controller::GetSafeSleepTime();
        }

        last_err = m_ErrHistory.back().err;
        integr_err = m_IntegrErr;
    }}

    unsigned int threads_cnt = pool->GetThreadsCount();
    if (last_err == 0
        ||  (last_err > 0  &&  threads_cnt == GetMaxThreads())
        ||  (last_err < 0  &&  threads_cnt == GetMinThreads()))
    {
        return CThreadPool_Controller::GetSafeSleepTime();
    }

    double sleep_time = 0;
    if (last_err > 0) {
        sleep_time = (m_Threshold - last_err - integr_err)
                     * m_IntegrCoeff / last_err;
    }
    else {
        sleep_time = (-m_Threshold - last_err - integr_err)
                     * m_IntegrCoeff / last_err;
    }
    if (sleep_time < 0)
        sleep_time = 0;

    return CTimeSpan(sleep_time);
}
コード例 #3
0
void
CThreadPool_Controller_PID::OnEvent(EEvent event)
{
    if (event == eSuspend) {
        return;
    }

    // All reads below are atomic reads of one variable, thus they cannot
    // return bad results. They can be a little bit inconsistent with each
    // other because of races with other threads but that's okay for the
    // purposes of this controller.
    unsigned int threads_count = GetPool()->GetThreadsCount();
    unsigned int queued_tasks  = GetPool()->GetQueuedTasksCount();
    unsigned int run_tasks     = GetPool()->GetExecutingTasksCount();

    if (threads_count == 0) {
        EnsureLimits();
        threads_count = GetMinThreads();

        // Special case when MinThreads == 0
        if (threads_count == 0) {
            if (queued_tasks == 0) {
                return;
            }

            threads_count = 1;
            SetThreadsCount(threads_count);
        }
    }

    double now_err = (double(queued_tasks + run_tasks) - threads_count)
                            / threads_count;
    double now_time = m_Timer.Elapsed();

    if (event == eResume) {
        // When we resuming we need to avoid panic because of big changes in
        // error value. So we will assume that current error value was began
        // long time ago and didn't change afterwards.
        m_ErrHistory.clear();
        m_ErrHistory.push_back(SThreadPool_PID_ErrInfo(now_time - m_DerivTime,
                                                       now_err));
    }

    double period = now_time - m_ErrHistory.back().call_time;

    if (now_err < 0  &&  threads_count == GetMinThreads()
        &&  m_IntegrErr <= 0)
    {
        now_err = 0;
    }

    double integr_err = m_IntegrErr + (now_err + m_ErrHistory.back().err) / 2
                                       * period / m_IntegrCoeff;

    while (m_ErrHistory.size() > 1
           &&  now_time - m_ErrHistory[1].call_time >= m_DerivTime)
    {
        m_ErrHistory.pop_front();
    }
    if (now_time - m_ErrHistory.back().call_time >= m_DerivTime / 10) {
        m_ErrHistory.push_back(SThreadPool_PID_ErrInfo(now_time, now_err));
        if (threads_count == GetMaxThreads()  &&  integr_err > m_Threshold) {
            m_IntegrErr = m_Threshold;
        }
        else if (threads_count == GetMinThreads()
                 &&  integr_err < -m_Threshold)
        {
            m_IntegrErr = -m_Threshold;
        }
        else {
            m_IntegrErr = integr_err;
        }
    }

    double deriv_err = (now_err - m_ErrHistory[0].err)
                        / m_DerivTime * m_DerivCoeff;

    double final_val = (now_err + integr_err + deriv_err) / m_Threshold;
/*
    LOG_POST(CTime(CTime::eCurrent).AsString("M/D/Y h:m:s.l").c_str()
             << "  count=" << threads_count << ", queued=" << queued_tasks
             << ", run=" << run_tasks << ", err=" << now_err << ", time=" << now_time
             << ", intErr=" << m_IntegrErr << ", derivErr=" << deriv_err
             << ", final=" << final_val << ", hist_size=" << m_ErrHistory.size());
*/
    if (final_val >= 1  ||  final_val <= -1) {
        if (final_val < 0 && -final_val > threads_count)
            SetThreadsCount(GetMinThreads());
        else
            SetThreadsCount(threads_count + int(final_val));
    }
    else {
        EnsureLimits();
    }
}