00001 /* 00002 * This file is part of libcxxsupport. 00003 * 00004 * libcxxsupport is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * libcxxsupport is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with libcxxsupport; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00017 */ 00018 00019 /* 00020 * libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik 00021 * and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt 00022 * (DLR). 00023 */ 00024 00025 /*! \file share_utils.h 00026 * Various convenience functions for subdividing tasks into chunks 00027 * 00028 * Copyright (C) 2002-2014 Max-Planck-Society 00029 * \author Martin Reinecke 00030 */ 00031 00032 #ifndef PLANCK_SHARE_UTILS_H 00033 #define PLANCK_SHARE_UTILS_H 00034 00035 #include "datatypes.h" 00036 00037 /*! Divides the index range [\a glo; \a ghi) into \a nshares approximately 00038 equal parts, and returns the sub-range [\a lo; \a hi) of the 00039 part with the number \a myshare (first part has index 0). */ 00040 inline void calcShareGeneral (int64 glo, int64 ghi, int64 nshares, 00041 int64 myshare, int64 &lo, int64 &hi) 00042 { 00043 int64 nwork = ghi-glo; 00044 int64 nbase = nwork/nshares; 00045 int64 additional = nwork%nshares; 00046 lo = glo+myshare*nbase + ((myshare<additional) ? myshare : additional); 00047 hi = lo+nbase+(myshare<additional); 00048 } 00049 00050 inline int64 shareSize (int64 glo, int64 ghi, int64 nshares, int64 myshare) 00051 { 00052 int64 nwork = ghi-glo; 00053 int64 nbase = nwork/nshares; 00054 int64 additional = nwork%nshares; 00055 return (myshare<additional) ? nbase+1 : nbase; 00056 } 00057 00058 /*! Helper class for dividing a range of work items into chunks of specified 00059 size. */ 00060 class chunkMaker 00061 { 00062 private: 00063 uint64 s_full, s_chunk, offset; 00064 00065 public: 00066 /*! Creates an object that produces chunk information for \a s_full_ 00067 work items and a desired chunk size of \a s_chunk_. 00068 \note Both \a s_chunk_ and \a s_full_ must be larger than 0. */ 00069 chunkMaker (uint64 s_full_, uint64 s_chunk_) 00070 : s_full(s_full_), s_chunk(s_chunk_), offset(0) {} 00071 00072 /*! Returns the total number of chunks. */ 00073 uint64 nchunks() const 00074 { return 1 + (s_full-1)/s_chunk; } 00075 00076 /*! Returns the start index of the next chunk in \a start, and its size 00077 in \a size. If all chunks have been processed already, the return 00078 value is \a false, else \a true. */ 00079 bool getNext (uint64 &start, uint64 &size) 00080 { 00081 using namespace std; 00082 if (offset>=s_full) return false; 00083 start=offset; 00084 size=min(s_chunk,s_full-offset); 00085 offset+=s_chunk; 00086 return true; 00087 } 00088 }; 00089 00090 #endif