223 lines
6.6 KiB
C++
223 lines
6.6 KiB
C++
#include <iostream>
|
|
#include <boost/thread.hpp>
|
|
#include <boost/chrono.hpp>
|
|
|
|
#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<double> ns (delta);
|
|
oss.fill ('0');
|
|
// typedef duration<int, ratio<86400> > days;
|
|
// auto d = duration_cast<days>(ns);
|
|
// ns -= d;
|
|
auto h = duration_cast<hours> (ns);
|
|
ns -= h;
|
|
auto m = duration_cast<minutes> (ns);
|
|
ns -= m;
|
|
oss << setw (2) << h.count () << ":"
|
|
<< setw (2) << m.count () << ":"
|
|
<< setw (9) << fixed << setprecision (6) << ns.count ();
|
|
return oss.str ();
|
|
}
|
|
|
|
// ========================================
|
|
template<typename DimImg, typename FunctId>
|
|
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<typename DimImg, typename FunctThreadId>
|
|
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<typename DimImg, typename FunctThreadMinMax>
|
|
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<DimImg> 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 <typename T>
|
|
void
|
|
TestThread::fillVector (vector<T> &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<long> sumSeq (coreCount, 0);
|
|
vector<long> 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<duration<double> > (startSeqRead-start).count ());
|
|
addTime (seqReadStats, duration_cast<duration<double> > (startParRead-startSeqRead).count ());
|
|
addTime (parReadStats, duration_cast<duration<double> > (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<typename T>
|
|
// 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<Index*> (ptr);
|
|
// ptr += utils::alignSize (count*sizeof (Index), alignment);
|
|
// ranks = reinterpret_cast<Rank *> (ptr);
|
|
// ptr += utils::alignSize (count*sizeof (Rank ), alignment);
|
|
// datas = reinterpret_cast<Data *> (ptr);
|
|
// }
|
|
// reset (d);
|
|
// }
|