distributed_queue.rst 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. .. Copyright (C) 2004-2008 The Trustees of Indiana University.
  2. Use, modification and distribution is subject to the Boost Software
  3. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. http://www.boost.org/LICENSE_1_0.txt)
  5. ================================
  6. |Logo| Distributed queue adaptor
  7. ================================
  8. ::
  9. template<typename ProcessGroup, typename Buffer>
  10. class distributed_queue
  11. {
  12. public:
  13. typedef ProcessGroup process_group_type;
  14. typedef Buffer buffer_type;
  15. typedef typename buffer_type::value_type value_type;
  16. typedef typename buffer_type::size_type size_type;
  17. explicit
  18. distributed_queue(const ProcessGroup& process_group = ProcessGroup(),
  19. const Buffer& buffer = Buffer(),
  20. bool polling = false);
  21. distributed_queue(const ProcessGroup& process_group, bool polling);
  22. void push(const value_type& x);
  23. void pop();
  24. value_type& top();
  25. const value_type& top() const;
  26. bool empty() const;
  27. size_type size() const;
  28. };
  29. template<typename ProcessGroup, typename Buffer>
  30. inline distributed_queue<ProcessGroup, Buffer>
  31. make_distributed_queue(const ProcessGroup& process_group, const Buffer& buffer,
  32. bool polling = false);
  33. Class template ``distributed_queue`` implements a distributed queue
  34. across a process group. The distributed queue is an adaptor over an
  35. existing (local) queue, which must model the Buffer_ concept. Each
  36. process stores a distinct copy of the local queue, from which it draws
  37. or removes elements via the ``pop`` and ``top`` members.
  38. The value type of the local queue must be a model of the
  39. `Global Descriptor`_ concept. The ``push`` operation of the
  40. distributed queue passes (via a message) the value to its owning
  41. processor. Thus, the elements within a particular local queue are
  42. guaranteed to have the process owning that local queue as an owner.
  43. Synchronization of distributed queues occurs in the ``empty`` and
  44. ``size`` functions, which will only return "empty" values (true or 0,
  45. respectively) when the entire distributed queue is empty. If the local
  46. queue is empty but the distributed queue is not, the operation will
  47. block until either condition changes. When the ``size`` function of a
  48. nonempty queue returns, it returns the size of the local queue. These
  49. semantics were selected so that sequential code that processes
  50. elements in the queue via the following idiom can be parallelized via
  51. introduction of a distributed queue:
  52. ::
  53. distributed_queue<...> Q;
  54. Q.push(x);
  55. while (!Q.empty()) {
  56. // do something, that may push a value onto Q
  57. }
  58. In the parallel version, the initial ``push`` operation will place
  59. the value ``x`` onto its owner's queue. All processes will
  60. synchronize at the call to empty, and only the process owning ``x``
  61. will be allowed to execute the loop (``Q.empty()`` returns
  62. false). This iteration may in turn push values onto other remote
  63. queues, so when that process finishes execution of the loop body
  64. and all processes synchronize again in ``empty``, more processes
  65. may have nonempty local queues to execute. Once all local queues
  66. are empty, ``Q.empty()`` returns ``false`` for all processes.
  67. The distributed queue can receive messages at two different times:
  68. during synchronization and when polling ``empty``. Messages are
  69. always received during synchronization, to ensure that accurate
  70. local queue sizes can be determines. However, whether ``empty``
  71. should poll for messages is specified as an option to the
  72. constructor. Polling may be desired when the order in which
  73. elements in the queue are processed is not important, because it
  74. permits fewer synchronization steps and less communication
  75. overhead. However, when more strict ordering guarantees are
  76. required, polling may be semantically incorrect. By disabling
  77. polling, one ensures that parallel execution using the idiom above
  78. will not process an element at a later "level" before an earlier
  79. "level".
  80. The distributed queue nearly models the Buffer_
  81. concept. However, the ``push`` routine does not necessarily
  82. increase the result of ``size()`` by one (although the size of the
  83. global queue does increase by one).
  84. Member Functions
  85. ----------------
  86. ::
  87. explicit
  88. distributed_queue(const ProcessGroup& process_group = ProcessGroup(),
  89. const Buffer& buffer = Buffer(),
  90. bool polling = false);
  91. Build a new distributed queue that communicates over the given
  92. ``process_group``, whose local queue is initialized via ``buffer`` and
  93. which may or may not poll for messages.
  94. -----------------------------------------------------------------------------
  95. ::
  96. distributed_queue(const ProcessGroup& process_group, bool polling);
  97. Build a new distributed queue that communicates over the given
  98. ``process_group``, whose local queue is default-initalized and which
  99. may or may not poll for messages.
  100. -----------------------------------------------------------------------------
  101. ::
  102. void push(const value_type& x);
  103. Push an element onto the distributed queue.
  104. The element will be sent to its owner process to be added to that
  105. process's local queue. If polling is enabled for this queue and
  106. the owner process is the current process, the value will be
  107. immediately pushed onto the local queue.
  108. Complexity: O(1) messages of size O(``sizeof(value_type)``) will be
  109. transmitted.
  110. -----------------------------------------------------------------------------
  111. ::
  112. void pop();
  113. Pop an element off the local queue. The queue must not be ``empty()``.
  114. -----------------------------------------------------------------------------
  115. ::
  116. value_type& top();
  117. const value_type& top();
  118. Returns the top element in the local queue. The queue must not be
  119. ``empty()``.
  120. -----------------------------------------------------------------------------
  121. ::
  122. bool empty() const;
  123. Determines if the queue is empty.
  124. When the local queue is nonempty, returns true. If the local queue is
  125. empty, synchronizes with all other processes in the process group
  126. until either (1) the local queue is nonempty (returns true) (2) the
  127. entire distributed queue is empty (returns false).
  128. -----------------------------------------------------------------------------
  129. ::
  130. size_type size() const;
  131. Determines the size of the local queue.
  132. The behavior of this routine is equivalent to the behavior of
  133. ``empty``, except that when ``empty`` returns true this
  134. function returns the size of the local queue and when ``empty``
  135. returns false this function returns zero.
  136. Free Functions
  137. --------------
  138. ::
  139. template<typename ProcessGroup, typename Buffer>
  140. inline distributed_queue<ProcessGroup, Buffer>
  141. make_distributed_queue(const ProcessGroup& process_group, const Buffer& buffer,
  142. bool polling = false);
  143. Constructs a distributed queue.
  144. -----------------------------------------------------------------------------
  145. Copyright (C) 2004, 2005 The Trustees of Indiana University.
  146. Authors: Douglas Gregor and Andrew Lumsdaine
  147. .. |Logo| image:: pbgl-logo.png
  148. :align: middle
  149. :alt: Parallel BGL
  150. :target: http://www.osl.iu.edu/research/pbgl
  151. .. _Global descriptor: GlobalDescriptor.html
  152. .. _Buffer: http://www.boost.org/libs/graph/doc/Buffer.html