⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 threads.h

📁 一个用来实现偏微分方程中网格的计算库
💻 H
字号:
// $Id: parallel.h 2631 2008-02-04 16:46:11Z roystgnr $// The libMesh Finite Element Library.// Copyright (C) 2002-2007  Benjamin S. Kirk, John W. Peterson  // This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version.  // This library 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// Lesser General Public License for more details.  // You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA#ifndef __threads_h__#define __threads_h__// System includes// Local includes#include "libmesh_config.h"// Threading building blocks includes#ifdef HAVE_TBB_API#  include "libmesh_logging.h" // only mess with the perflog if we are really multithreaded#  include "tbb/tbb_stddef.h"#  include "tbb/blocked_range.h"#  include "tbb/parallel_for.h"#  include "tbb/parallel_reduce.h"#  include "tbb/task_scheduler_init.h"#  include "tbb/partitioner.h"#  include "tbb/spin_mutex.h"#  include "tbb/atomic.h"#endif/** * The Threads namespace is for wrapper functions * for common general multithreading algorithms and tasks. */namespace Threads{#ifdef HAVE_TBB_API  //-------------------------------------------------------------------  /**   * Scheduler to manage threads.   */  typedef tbb::task_scheduler_init task_scheduler_init;  //-------------------------------------------------------------------  /**   * Dummy "splitting object" used to distinguish splitting constructors   * from copy constructors.   */  typedef tbb::split split;  //-------------------------------------------------------------------  /**   * Exectue the provided function object in parallel on the specified    * range.   */  template <typename Range, typename Body>  inline  void parallel_for (const Range &range, const Body &body)  {#ifdef ENABLE_PERFORMANCE_LOGGING    if (libMesh::n_threads() > 1)      libMesh::perflog.disable_logging();#endif       tbb::parallel_for (range, body, tbb::auto_partitioner()); #ifdef ENABLE_PERFORMANCE_LOGGING    if (libMesh::n_threads() > 1)      libMesh::perflog.enable_logging();#endif  }  //-------------------------------------------------------------------  /**   * Exectue the provided function object in parallel on the specified    * range with the specified partitioner.   */  template <typename Range, typename Body, typename Partitioner>  inline  void parallel_for (const Range &range, const Body &body, const Partitioner &partitioner)  { #ifdef ENABLE_PERFORMANCE_LOGGING    if (libMesh::n_threads() > 1)      libMesh::perflog.disable_logging();#endif       tbb::parallel_for (range, body, partitioner); #ifdef ENABLE_PERFORMANCE_LOGGING    if (libMesh::n_threads() > 1)      libMesh::perflog.enable_logging();#endif  }  //-------------------------------------------------------------------  /**   * Exectue the provided reduction operation in parallel on the specified    * range.   */  template <typename Range, typename Body>  inline  void parallel_reduce (const Range &range, Body &body)  { #ifdef ENABLE_PERFORMANCE_LOGGING    if (libMesh::n_threads() > 1)      libMesh::perflog.disable_logging();#endif       tbb::parallel_reduce (range, body, tbb::auto_partitioner()); #ifdef ENABLE_PERFORMANCE_LOGGING    if (libMesh::n_threads() > 1)      libMesh::perflog.enable_logging();#endif  }  //-------------------------------------------------------------------  /**   * Exectue the provided reduction operation in parallel on the specified    * range with the specified partitioner.   */  template <typename Range, typename Body, typename Partitioner>  inline  void parallel_reduce (const Range &range, Body &body, const Partitioner &partitioner)  { #ifdef ENABLE_PERFORMANCE_LOGGING    if (libMesh::n_threads() > 1)      libMesh::perflog.disable_logging();#endif       tbb::parallel_reduce (range, body); #ifdef ENABLE_PERFORMANCE_LOGGING    if (libMesh::n_threads() > 1)      libMesh::perflog.enable_logging();#endif  }  //-------------------------------------------------------------------  /**   * Spin mutex.  Implements mutual exclusion by busy-waiting in user   * space for the lock to be acquired.   */  typedef tbb::spin_mutex spin_mutex;  //-------------------------------------------------------------------  /**   * Defines atomic operations which can only be executed on a    * single thread at a time.  This is used in reference counting,   * for example, to allow count++/count-- to work.   */  template <typename T>  class atomic : public tbb::atomic<T> {};  #else //HAVE_TBB_API  //-------------------------------------------------------------------  /**   * Scheduler to manage threads.   */  class task_scheduler_init  {  public:    static const int automatic = -1;    task_scheduler_init (int = automatic) {};    void initialize (int = automatic) {};    void terminate () {};      };  //-------------------------------------------------------------------  /**   * Dummy "splitting object" used to distinguish splitting constructors   * from copy constructors.   */  class split {};  //-------------------------------------------------------------------  /**   * Exectue the provided function object in parallel on the specified    * range.   */  template <typename Range, typename Body>  inline  void parallel_for (const Range &range, const Body &body)  { body(range); }  //-------------------------------------------------------------------  /**   * Exectue the provided function object in parallel on the specified    * range with the specified partitioner.   */  template <typename Range, typename Body, typename Partitioner>  inline  void parallel_for (const Range &range, const Body &body, const Partitioner &)  { body(range); }  //-------------------------------------------------------------------  /**   * Exectue the provided reduction operation in parallel on the specified    * range.   */  template <typename Range, typename Body>  inline  void parallel_reduce (const Range &range, Body &body)  { body(range); }  //-------------------------------------------------------------------  /**   * Exectue the provided reduction operation in parallel on the specified    * range with the specified partitioner.   */  template <typename Range, typename Body, typename Partitioner>  inline  void parallel_reduce (const Range &range, Body &body, const Partitioner &)  { body(range); }  //-------------------------------------------------------------------  /**   * Spin mutex.  Implements mutual exclusion by busy-waiting in user   * space for the lock to be acquired.   */  class spin_mutex   {  public:    spin_mutex() {}    class scoped_lock     {    public:      scoped_lock () {}      scoped_lock ( spin_mutex&  ) {}       void acquire ( spin_mutex& ) {}      void release () {}    };  };  //-------------------------------------------------------------------  /**   * Defines atomic operations which can only be executed on a    * single thread at a time.   */  template <typename T>  class atomic  {  public:    atomic () : _val(0) {}    operator T& () { return _val; }  private:    T _val;  };  #endif // #ifdef HAVE_TBB_API//   /**//    * Blocked range which can be subdivided and executed in parallel.//    *///   template <typename T>//   class BlockedRange //   {//   public://     /**//      * Allows an \p StoredRange to behave like an STL container.//      *///     typedef T const_iterator;//     /**//      * Constructor. Optionally takes the \p grainsize parameter, which is the//      * smallest chunk the range may be broken into for parallel//      * execution.//      *///     BlockedRange (const unsigned int grainsize = 1000) ://       _grainsize(grainsize)//     {}//     /**//      * Constructor.  Takes the beginning and end of the range.  //      * Optionally takes the \p grainsize parameter, which is the//      * smallest chunk the range may be broken into for parallel//      * execution.//      *///     BlockedRange (const const_iterator first,// 		  const const_iterator last,// 		  const unsigned int grainsize = 1000) ://       _grainsize(grainsize)//     {//       this->reset(first, last);//     }//     /**//      * Copy constructor.  The \p StoredRange can be copied into//      * subranges for parallel execution.  In this way the //      * initial \p StoredRange can be thought of as the root of//      * a binary tree.  The root element is the only element//      * which interacts with the user.  It takes a specified//      * range of objects and packs it into a contiguous vector//      * which can be split efficiently. However, there is no need//      * for the child ranges to contain this vector, so long as//      * the parent outlives the children.  So we implement//      * the copy constructor to specifically omit the \p _objs//      * vector.//      *///     BlockedRange (const BlockedRange<T> &r)://       _end(r._end), //       _begin(r._begin),//       _grainsize(r._grainsize)//     {}    //     /**//      * Splits the range \p r.  The first half//      * of the range is left in place, the second//      * half of the range is placed in *this.//      *///     BlockedRange (BlockedRange<T> &r, Threads::split ) : //       _end(r._end),//       _begin(r._begin),//       _grainsize(r._grainsize)//     {//       const_iterator// 	beginning = r._begin,// 	ending    = r._end,// 	middle    = beginning + (ending - beginning)/2u;    //       r._end = _begin = middle;//     }    //     /**//      * Resets the \p StoredRange to contain [first,last).//      */ //     void reset (const const_iterator first,// 		const const_iterator last)//     {//       _begin = first;//       _end   = last;//     }    //     /**//      * Beginning of the range.//      *///     const_iterator begin () const { return _begin; }      //     /**//      * End of the range.//      *///     const_iterator end () const { return _end; }    //     /**//      * The grain size for the range.  The range will be subdivided into //      * subranges not to exceed the grain size.//      *///     unsigned int grainsize () const {return _grainsize;}    //     /**//      * Set the grain size.//      *///     void grainsize (const unsigned int &gs) {_grainsize = gs;}    //     /**//      * \return the size of the range.//      *///     int size () const { return (_end -_begin); }//     //------------------------------------------------------------------------//     // Methods that implement Range concept//     //------------------------------------------------------------------------    //     /**//      * Returns true if the range is empty.//      */  //     bool empty() const { return (_begin == _end); }    //     /**//      * Returns true if the range can be subdivided.//      *///     bool is_divisible() const { return static_cast<int>(this->grainsize()) < (_end - _begin); }//   private:    //     const_iterator _end;//     const_iterator _begin;//     unsigned int _grainsize;//   };    /**   * A spin mutex object which    */  extern spin_mutex spin_mtx;} // namespace Threads#endif // #define __threads_h__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -