#include #include #include #include "triskeleDealThreads.hpp" #include "TestThread.hpp" using namespace std; using namespace boost::chrono; using namespace triskele; using namespace otb; using namespace otb::triskele; static string timeTypeLabels [TimeTypeCard] = { "directDeal", "lambdaDeal", "threadDeal", "inThreadDeal", "initStats", "seqReadStats", "parReadStats", "seqWriteStats", "parWriteStats", "seqRWStats", "parRWStats" }; const unsigned int TestThread::maxCoreCount = boost::thread::hardware_concurrency (); // ======================================== inline string TestThread::ns2string (double delta) { ostringstream oss; duration ns (delta); oss.fill ('0'); // typedef duration > days; // auto d = duration_cast(ns); // ns -= d; auto h = duration_cast (ns); ns -= h; auto m = duration_cast (ns); ns -= m; oss << setw (2) << h.count () << ":" << setw (2) << m.count () << ":" << setw (9) << fixed << setprecision (6) << ns.count (); return oss.str (); } // ======================================== template inline void nodealThreadRange (const DimImg &maxId, const unsigned int &coreCount, const FunctId &functId/* functId (id) */) { nodealThread (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 nodealThreadThreadRange (const DimImg &maxId, const unsigned int &coreCount, const FunctThreadId &functThreadId/* functThreadId (threadId, id) */) { nodealThread (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 nodealThread (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); for (unsigned int idCopyValInThread = 0; idCopyValInThread < coreCount; ++idCopyValInThread) { functThreadMinMax (idCopyValInThread, maxIds[idCopyValInThread], maxIds[idCopyValInThread+1]); } } // ======================================== TestThread::TestThread (const unsigned int &coreCount) : coreCount (coreCount), global (nbItem*coreCount, 0) { } ostream & TestThread::print (ostream &out, const AlgoStat stats[]) { out << endl << setw (16) << left << "Time" << "\t" << setw (15) << left << "Sum" << "\t" << setw (3) << left << "Count" << "\t" << setw (15) << left << "Mean" << "\t" << setw (15) << left << "Min" << "\t" << setw (15) << left << "Max" << endl; for (unsigned int i = 0; i < TimeTypeCard; ++i) { if (!ba::count (stats[i])) continue; out << setw (16) << right << timeTypeLabels[i] << "\t" << ns2string (ba::sum (stats[i])) << "\t" << setw (3) << ba::count (stats[i]) << "\t" << ns2string (ba::mean (stats[i])) << "\t" << ns2string (ba::min (stats[i])) << "\t" << ns2string (ba::max (stats[i])) << endl << flush; } return out; } template void TestThread::fillVector (vector &vect) { for (size_t i = 0; i < vect.size (); ++i) vect[i] = (T) std::rand (); } // show algin void TestThread::multiTest () { for (int i = 0; i < 100; ++i) { vector sumSeq (coreCount, 0); vector sumPar (coreCount, 0); auto start = high_resolution_clock::now (); fillVector (global); // lecture seq => faire somme auto startSeqRead = high_resolution_clock::now (); nodealThreadThreadRange (nbItem, coreCount, [this, &sumSeq] (const unsigned int &threadId, const DimImg &item) { sumSeq[threadId] += global[item]; }); // lecture // => faire somme auto startParRead = high_resolution_clock::now (); dealThreadThreadRange (nbItem, coreCount, [this, &sumPar] (const unsigned int &threadId, const DimImg &item) { sumPar[threadId] += global[item]; }); // XXX vérifier égalité de sumSeq sumPar // écriture seq => écrire idx // écriture // => écrire idx // lecture/écriture seq => écrire x/2 // lecture/écriture // => écrire x/2 auto end = high_resolution_clock::now (); addTime (initStats, duration_cast > (startSeqRead-start).count ()); addTime (seqReadStats, duration_cast > (startParRead-startSeqRead).count ()); addTime (parReadStats, duration_cast > (end-startParRead).count ()); } print (cout, timeStats); } // ======================================== int main (int argc, char** argv) { cout << "start test" << endl; srand (time (NULL)); TestThread tt; //tt.multiTest (); for (int i = 0; i < 100; ++i) tt.testDeal (); tt.print (cout, tt.timeStats); return 0; } // namespace utils { // inline size_t alignSize(size_t size, size_t alignment) { // return (size+alignment-1)&~(alignment-1); // } // template // inline T * alignPtr(T * ptr, uintptr_t alignment) { // union { // T *p; // uintptr_t u; // } u; // u.p = ptr; // u.u = (u.u+alignment-1)&~(alignment-1); // return u.p; // } // }//namespace utils // void init (Index c, Data const &d) { // if (count != c) { // kill (); // count = c; // size_t const alignment = 64; // size_t size = alignment-1 // + utils::alignSize (count*sizeof (Index), alignment) // + utils::alignSize (count*sizeof (Rank ), alignment) // + utils::alignSize (count*sizeof (Data ), alignment); // //memory.reset (new char[size]); // delete [] memory; // memory = nullptr; // memory = new char[size]; // char *ptr = utils::alignPtr (memory, alignment); // parents = reinterpret_cast (ptr); // ptr += utils::alignSize (count*sizeof (Index), alignment); // ranks = reinterpret_cast (ptr); // ptr += utils::alignSize (count*sizeof (Rank ), alignment); // datas = reinterpret_cast (ptr); // } // reset (d); // }