#ifndef _TRISKELE_DEAL_THREADS_TPP #define _TRISKELE_DEAL_THREADS_TPP // ======================================== template inline void dealThreadRange (const DimImg &maxId, const unsigned int &coreCount, const FunctId &functId/* functId (id) */) { dealThread (maxId, coreCount, [&functId] (const unsigned int &threadId, const DimImg &minVal, const DimImg &maxVal) { for (DimImg id = minVal; id < maxVal; ++id) functId (id); }); } // ---------------------------------------- template inline void dealThreadThreadRange (const DimImg &maxId, const unsigned int &coreCount, const FunctThreadId &functThreadId/* functThreadId (threadId, id) */) { dealThread (maxId, coreCount, [&functThreadId] (const unsigned int &threadId, const DimImg &minVal, const DimImg &maxVal) { for (DimImg id = minVal; id < maxVal; ++id) functThreadId (threadId, id); }); } // ---------------------------------------- template inline void dealThreadBound (const DimImg &maxId, const unsigned int &coreCount, const FunctMinMax &functMinMax/* functMinMax (minVal, maxVal) */) { dealThread (maxId, coreCount, [&functMinMax] (const unsigned int &threadId, const DimImg &minVal, const DimImg &maxVal) { functMinMax (minVal, maxVal); }); } // ---------------------------------------- template inline std::vector getDealThreadBounds (const DimImg &maxId, const unsigned int &coreCount) { if (!maxId || !coreCount) return std::vector (0); DimImg average = maxId/coreCount; std::vector maxIds (coreCount+1, average); for (unsigned int core = 0; core < coreCount; ++core) maxIds[core] = DimImg (core*average); maxIds[coreCount] = maxId; return maxIds; } // ---------------------------------------- template inline void dealThread (const DimImg &maxId, unsigned int coreCount, const FunctThreadMinMax &functThreadMinMax/* functThreadMinMax (threadId, minVal, maxVal) */) { //DEF_LOG ("dealThreadBound", "coreCount:" << coreCount << " maxId:" << maxId); if (!maxId || !coreCount) return; if (DimImg (coreCount) > maxId) coreCount = (unsigned int) maxId; if (coreCount == 1) { functThreadMinMax (0, 0, maxId); return; } std::vector maxIds = getDealThreadBounds (maxId, coreCount); #ifdef THREAD_DISABLE for (unsigned int idCopyValInThread = 0; idCopyValInThread < coreCount; ++idCopyValInThread) { functThreadMinMax (idCopyValInThread, maxIds[idCopyValInThread], maxIds[idCopyValInThread+1]); } #elif INTEL_TBB_THREAD using namespace tbb; #pragma warning(disable: 588) parallel_for (size_t (0), size_t (coreCount), [&maxIds, &functThreadMinMax] (size_t idCopyValInThread) { functThreadMinMax (idCopyValInThread, maxIds[idCopyValInThread], maxIds[idCopyValInThread+1]); }); #else /* BOOST thread */ std::vector tasks; for (unsigned int idCopyValInThread = 0; idCopyValInThread < coreCount; ++idCopyValInThread) { tasks.push_back (boost::thread ([/*no ref!!!*/idCopyValInThread, &maxIds, &functThreadMinMax] () { functThreadMinMax (idCopyValInThread, maxIds[idCopyValInThread], maxIds[idCopyValInThread+1]); })); } for (unsigned int i = 0; i < coreCount; ++i) tasks[i].join (); #endif } // ======================================== template inline void dealThreadFill_n (const DimImg &maxId, unsigned int coreCount, OutputIterator first, const T& val) { dealThreadBound (maxId, coreCount, [&first, &val] (const DimImg &minVal, const DimImg &maxVal) { fill_n (first+minVal, maxVal-minVal, val); }); } // ======================================== template inline void callOnSortedSets (const std::vector &sizes, const WeightFunct &getWeight/* getWeight (vectId, itemId) */, CmpFunct isWeightInf/* isWeightInf (w1, w2) */, const CallFunct &callIdId/* callIdId (vectId, itemId) */) { DimImg size = sizes.size (); DEF_LOG ("callOnSortedSets", "size:" << size); if (!size) return; std::vector vectIds (size, 0); std::vector vectCounts (sizes); // get min bool found = false; DimImg minVectIdx = 0; WeightT maxWeight = 0; for (DimImg vectId = 0; vectId < size; ++vectId) { if (!vectCounts [vectId]) continue; WeightT tmpWeight = getWeight (vectId, 0); if (found && !isWeightInf (tmpWeight, maxWeight)) continue; minVectIdx = vectId; maxWeight = tmpWeight; found = true; } LOG ("found:" << found << " minVectIdx:" << minVectIdx << " maxWeight:" << maxWeight); // loop for ( ; found; ) { // get next min found = false; DimImg nextMinVectIdx = 0; WeightT nextMaxWeight = 0; for (DimImg vectId = minVectIdx; ; ) { if (vectCounts [vectId]) { WeightT tmpWeight = getWeight (vectId, vectIds [vectId]); if (!isWeightInf (maxWeight, tmpWeight)) { // maxWeight == tmpWeight callIdId (vectId, vectIds [vectId]); ++vectIds [vectId]; --vectCounts [vectId]; continue; } if (!found || isWeightInf (tmpWeight, nextMaxWeight)) { nextMinVectIdx = vectId; nextMaxWeight = tmpWeight; found = true; } } vectId = (vectId+1)%size; if (vectId == minVectIdx) break; } minVectIdx = nextMinVectIdx; maxWeight = nextMaxWeight; } } #endif // _TRISKELE_DEAL_THREADS_TPP