# equally_split.h

Go to the documentation of this file.

    00001 // -*- C++ -*-
    00002
    00003 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
    00004 //
    00005 // This file is part of the GNU ISO C++ Library.  This library is free
    00006 // software; you can redistribute it and/or modify it under the terms
    00007 // of the GNU General Public License as published by the Free Software
    00008 // Foundation; either version 3, or (at your option) any later
    00009 // version.
    00010
    00011 // This library is distributed in the hope that it will be useful, but
    00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
    00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00014 // General Public License for more details.
    00015
    00016 // Under Section 7 of GPL version 3, you are granted additional
    00017 // permissions described in the GCC Runtime Library Exception, version
    00018 // 3.1, as published by the Free Software Foundation.
    00019
    00020 // You should have received a copy of the GNU General Public License and
    00021 // a copy of the GCC Runtime Library Exception along with this program;
    00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    00023 // <http://www.gnu.org/licenses/>.
    00024
    00025 /** @file parallel/equally_split.h
    00026  *  This file is a GNU parallel extension to the Standard C++ Library.
    00027  */
    00028
    00029 // Written by Johannes Singler.
    00030
    00031 #ifndef _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H
    00032 #define _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H 1
    00033
    00034 namespace __gnu_parallel
    00035 {
    00036   /** @brief function to split a sequence into parts of almost equal size.
    00037    *
    00038    *  The resulting sequence __s of length __num_threads+1 contains the
    00039    *  splitting positions when splitting the range [0,__n) into parts of
    00040    *  almost equal size (plus minus 1).  The first entry is 0, the last
    00041    *  one n. There may result empty parts.
    00042    *  @param __n Number of elements
    00043    *  @param __num_threads Number of parts
    00044    *  @param __s Splitters
    00045    *  @returns End of __splitter sequence, i.e. @c __s+__num_threads+1 */
    00046   template<typename _DifferenceType, typename _OutputIterator>
    00047     _OutputIterator
    00048     equally_split(_DifferenceType __n, _ThreadIndex __num_threads,
    00049           _OutputIterator __s)
    00050     {
    00051       _DifferenceType __chunk_length = __n / __num_threads;
    00052       _DifferenceType __num_longer_chunks = __n % __num_threads;
    00053       _DifferenceType __pos = 0;
    00054       for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
    00055     {
    00056       *__s++ = __pos;
    00057       __pos += ((__i < __num_longer_chunks)
    00058             ? (__chunk_length + 1) : __chunk_length);
    00059     }
    00060       *__s++ = __n;
    00061       return __s;
    00062     }
    00063
    00064   /** @brief function to split a sequence into parts of almost equal size.
    00065    *
    00066    *  Returns the position of the splitting point between
    00067    *  thread number __thread_no (included) and
    00068    *  thread number __thread_no+1 (excluded).
    00069    *  @param __n Number of elements
    00070    *  @param __num_threads Number of parts
    00071    *  @returns splitting point */
    00072   template<typename _DifferenceType>
    00073     _DifferenceType
    00074     equally_split_point(_DifferenceType __n,
    00075             _ThreadIndex __num_threads,
    00076             _ThreadIndex __thread_no)
    00077     {
    00078       _DifferenceType __chunk_length = __n / __num_threads;
    00079       _DifferenceType __num_longer_chunks = __n % __num_threads;
    00080       if (__thread_no < __num_longer_chunks)
    00081     return __thread_no * (__chunk_length + 1);
    00082       else
    00083     return __num_longer_chunks * (__chunk_length + 1)
    00084           + (__thread_no - __num_longer_chunks) * __chunk_length;
    00085     }
    00086 }
    00087
    00088 #endif /* _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H */