equally_split.h 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // -*- C++ -*-
  2. // Copyright (C) 2007-2022 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the terms
  6. // of the GNU General Public License as published by the Free Software
  7. // Foundation; either version 3, or (at your option) any later
  8. // version.
  9. // This library is distributed in the hope that it will be useful, but
  10. // WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. // General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file parallel/equally_split.h
  21. * This file is a GNU parallel extension to the Standard C++ Library.
  22. */
  23. // Written by Johannes Singler.
  24. #ifndef _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H
  25. #define _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H 1
  26. namespace __gnu_parallel
  27. {
  28. /** @brief function to split a sequence into parts of almost equal size.
  29. *
  30. * The resulting sequence __s of length __num_threads+1 contains the
  31. * splitting positions when splitting the range [0,__n) into parts of
  32. * almost equal size (plus minus 1). The first entry is 0, the last
  33. * one n. There may result empty parts.
  34. * @param __n Number of elements
  35. * @param __num_threads Number of parts
  36. * @param __s Splitters
  37. * @returns End of __splitter sequence, i.e. @c __s+__num_threads+1 */
  38. template<typename _DifferenceType, typename _OutputIterator>
  39. _OutputIterator
  40. __equally_split(_DifferenceType __n, _ThreadIndex __num_threads,
  41. _OutputIterator __s)
  42. {
  43. _DifferenceType __chunk_length = __n / __num_threads;
  44. _DifferenceType __num_longer_chunks = __n % __num_threads;
  45. _DifferenceType __pos = 0;
  46. for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
  47. {
  48. *__s++ = __pos;
  49. __pos += ((__i < __num_longer_chunks)
  50. ? (__chunk_length + 1) : __chunk_length);
  51. }
  52. *__s++ = __n;
  53. return __s;
  54. }
  55. /** @brief function to split a sequence into parts of almost equal size.
  56. *
  57. * Returns the position of the splitting point between
  58. * thread number __thread_no (included) and
  59. * thread number __thread_no+1 (excluded).
  60. * @param __n Number of elements
  61. * @param __num_threads Number of parts
  62. * @param __thread_no Number of threads
  63. * @returns splitting point */
  64. template<typename _DifferenceType>
  65. _DifferenceType
  66. __equally_split_point(_DifferenceType __n,
  67. _ThreadIndex __num_threads,
  68. _ThreadIndex __thread_no)
  69. {
  70. _DifferenceType __chunk_length = __n / __num_threads;
  71. _DifferenceType __num_longer_chunks = __n % __num_threads;
  72. if (__thread_no < __num_longer_chunks)
  73. return __thread_no * (__chunk_length + 1);
  74. else
  75. return __num_longer_chunks * (__chunk_length + 1)
  76. + (__thread_no - __num_longer_chunks) * __chunk_length;
  77. }
  78. }
  79. #endif /* _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H */