Changeset 3177 in Sophya for trunk/SophyaProg/Tests/zthr.cc


Ignore:
Timestamp:
Feb 6, 2007, 9:19:44 AM (19 years ago)
Author:
ansari
Message:

Ajout de test avec synchronisation entre threads dans zthr.cc , Reza 06/02/2007

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaProg/Tests/zthr.cc

    r3080 r3177  
    77
    88#include "tmatrix.h"
     9#include "tvector.h"
    910#include "tarrinit.h"
    1011
     
    1819  csh> time zthr mtx 2 500
    1920  csh> time zthr arr 2 500
     21  csh> time zthr sync 4 1000
    2022*/
    2123 
     
    2426
    2527#include "timing.h"
     28#include "ctimer.h"
    2629
    2730
    2831// --- Structure d'argument pour fonction d'execution dans les threads de test
    2932typedef struct  {
    30   int thid;
    31   int M;
     33  int_4 thid;
     34  int_4 M;
    3235} ztarg;
    3336
     
    9194
    9295
     96// Structure de gestion utilisee par la classe MTVecPool
     97typedef struct {
     98  bool busy;
     99  int stat;
     100} St_VecPool;
     101
     102// -------------------------------------------------------------------
     103// Structure de gestion de zones memoire partagee (des vecteurs) entre
     104// threads - qui doivent operer successivement sur les vecteurs
     105// -------------------------------------------------------------------
     106class MTVecPool {
     107public:
     108  MTVecPool(uint_4 nth, uint_4 vsz, uint_4 nvec)
     109  {
     110    if (nth > 60) throw ParmError("MTVecPool::MTVecPool() nth > 60");
     111    if ((nth < 1) || (vsz < 2))
     112        throw ParmError("MTVecPool::MTVecPool() nth<1 OR vsz<2 ");
     113    _vmx.SetSize(vsz, nvec);
     114    _nth = nth;
     115    _vsz = vsz;
     116    cout << "-- MTVecPool(nth=" << nth << ")" << endl;
     117    _vmx.Show();
     118  }
     119  ~MTVecPool()   { }
     120  // Renvoie un pointeur de vecteur pour thread tid
     121  TVector<int_8>  GetVec(uint_4 tid, uint_4& idx)
     122  {
     123    if (tid >= _nth) ParmError("MTVecPool::getvec() tid > _nth");
     124    //DBG  cout << "DBG-GetVec(tid= " << tid << ")" << endl;
     125    if (tid == 0) {
     126      mex.lock();
     127      St_VecPool stv;
     128      idx = _vecs.size();
     129      stv.busy = true;
     130      stv.stat = 0;
     131      _vecs.push_back(stv);
     132      mex.unlock();
     133      //DBG cout << "DBG-GetVec(tid= " << tid << ") -> Idx=" << idx << " VecSz=" << _vmx.Column(idx).Size() << endl;
     134      return (_vmx.Column(idx));
     135    }
     136    else {
     137      mex.lock();
     138      bool found = false;
     139      while (!found) {
     140        for(uint_4 k=0; k<_vecs.size(); k++) {
     141          if ( (_vecs[k].stat == tid) && (! _vecs[k].busy) ) {
     142            found = true;  idx = k;
     143            _vecs[k].stat = tid; _vecs[k].busy = true;
     144            break;
     145          }
     146        }
     147        if (found) {
     148          mex.unlock();
     149          //DBG  cout << "DBG-GetVec(tid= " << tid << ") -> nv=" << hex << rv << dec << endl;
     150          return (_vmx.Column(idx));
     151        }
     152        else {
     153          mex.broadcast();
     154          mex.wait();
     155        }
     156      }
     157    }
     158  }
     159
     160  // Retourne le pointeur de vecteur au gestionnaire, qui le marque comme disponible
     161  void RetVec(uint_4 idx)
     162  {
     163    //DBG cout << "DBG-RetVec(idx= " << idx << ")" << endl;
     164    ZSync zs(mex, 2);
     165    _vecs[idx].busy = false; _vecs[idx].stat++;
     166    zs.NOp();
     167  }
     168
     169  // Verifie l'etat memoire de tous les vecteurs et fait des print
     170  int Check()
     171  {
     172    cout << "MTVecPool::Check() NVec=" << _vecs.size() << " VSz="
     173         << _vsz << " NThreads=" << _nth << endl;
     174    int nerr = 0;
     175    int_8 sum = 0;
     176    int_8 p2 = 1;
     177    int_8 min,max;
     178    for(int i=0; i<_nth; i++) { sum += p2; p2 *= 2; }
     179    for(uint_4 k=0; k<_vecs.size(); k++) {
     180      if ( (_vecs[k].busy) || (_vecs[k].stat != _nth) ) {
     181        cout << " Check()/Pb Busy Or Stat  for k=" << k << endl;
     182        nerr++;
     183      }
     184      _vmx.Column(k) -= sum;
     185      _vmx.Column(k).MinMax(min, max);
     186      if ((min!=0) || (max!=0)) {
     187        cout << " Check()/Pb vec[k=" << k << "] != (sum=" << sum << ")" << endl;
     188        nerr++;
     189      }
     190    }
     191    if (nerr == 0) cout << "MTVecPool::Check()  - OK (NErr=0)" << endl;
     192    else cout << "MTVecPool::Check() PB NErr=" << nerr << endl;
     193    return nerr;
     194  }
     195
     196  // ... variables membres
     197  ZMutex mex;
     198  uint_4 _vsz;
     199  uint_4 _nth;
     200  TMatrix<int_8> _vmx;
     201  vector< St_VecPool> _vecs;
     202};
     203
     204
     205static MTVecPool* mtvp = NULL;
     206
     207// --- fonction de test avec synchronisation entre threads
     208void sync_funzt(void *arg)
     209{
     210  ztarg * za = (ztarg *)arg;
     211  cout << ">>>> sync_funzt(ThId=" << za->thid << ") - NVec/NLoop= " << za->M << endl;
     212 
     213  if (mtvp == NULL)
     214    throw NullPtrError("sync_funzt: MTVecPool* mtvp = NULL");
     215
     216  int_4 L = za->M;
     217  int_8 p2 = 1;
     218  uint_4 k, tid;
     219  tid = za->thid;
     220  for(k=0; k<tid; k++) p2 *= 2;
     221
     222  char buff[128];
     223  sprintf(buff, "sync_funzt(ThId=%d) StarOfLoop", za->thid);
     224  PrtTim(buff);
     225  uint_4 idx;
     226  for(k=0; k<L; k++) {
     227    mtvp->GetVec(tid, idx) += p2;
     228    //DBG cout << "DBG-sync_funzt(tid=" << tid << ", idx=" << idx << endl;
     229    mtvp->RetVec(idx);
     230  }
     231  sprintf(buff, "sync_funzt(ThId=%d) EndOfLoop", za->thid);
     232  PrtTim(buff);
     233  return;
     234}
    93235
    94236class CountLock : public ZMutex {
     
    103245static int N = 1;
    104246static int M = 5;
     247static int VSZ = 128;
    105248
    106249int main(int narg, char *arg[])
     
    109252
    110253  if (narg < 4) {
    111     cout << " Usage: zthr select N LM" << endl;
     254    cout << " Usage: zthr select N LM [Sz] " << endl;
    112255    cout << "  select= sl -> simple loop with sleep " << endl;
    113256    cout << "  select= mtx -> matrix init and multiply mx1*mx2" << endl;
    114257    cout << "  select= arr -> array/matrix init and operation c1*a1+c2*a2 " << endl;
    115258    cout << "  select= clk -> Mutex lock count  " << endl;
     259    cout << "  select= sync -> Thread synchronisation using ZMutex" << endl;
    116260    cout << "  N= Number of threads (sl/mtx) or CountLock " << endl;
    117     cout << "  LM = Loop limit (sl) or Matrix size (mtx) " << endl;
     261    cout << "  LM = Loop limit (sl/sync) or Matrix size (mtx) " << endl;
     262    cout << "  Sz = Vector size for select=sync (default=256) " << endl;
    118263    return(1);
    119264  }
    120265
    121266  string sel = arg[1];
    122   if ((sel != "sl") && (sel != "mtx") && (sel != "arr") && (sel != "clk")) {
     267  if ((sel != "sl") && (sel != "mtx") && (sel != "arr") &&
     268      (sel != "sync") && (sel != "clk")) {
    123269    cout << "zthr/erreur argument sel (!= sl / mtx / arr / clk) " << endl;
    124270    return 2;
     
    128274  N = atoi(arg[2]);
    129275  M = atoi(arg[3]);
    130   cout << "zthr/Info: select=" << sel << " N=" << N << " M= " << M << endl;
     276  if (narg > 4) VSZ = atoi(arg[4]);
     277  cout << "zthr/Info: select=" << sel << " N=" << N << " M= " << M
     278       << " VSz=" << VSZ << endl;
    131279 
    132280 
     
    136284  int rc = 0;
    137285  try {
    138     ResourceUsage res;
    139     if ((sel == "mtx") || (sel == "arr") || (sel == "sl")) {
     286    ResourceUsage res(ResourceUsage::RU_All);
     287    if ((sel == "mtx") || (sel == "arr") || (sel == "sl") || (sel == "sync") ) {
     288      if (sel == "sync") mtvp = new MTVecPool(N,VSZ,M);
    140289      vector<ztarg *> vza;
    141290      vector<ZThread *> vzth;
     
    145294        ztarg* zap = new ztarg;
    146295        vzth.push_back(pzt);
    147         zap->thid = i+1;  zap->M = M;
     296        // ATTENTION : il faut que le thid = 0 ... N-1 (et pas 1)
     297        zap->thid = i;  zap->M = M;
    148298        vza.push_back(zap);
    149299        if (sel == "mtx")  pzt->setAction(mtx_funzt, vza[i]);
    150300        else if (sel == "arr")  pzt->setAction(arr_funzt, vza[i]);
     301        else if (sel == "sync")  pzt->setAction(sync_funzt, vza[i]);
    151302        else pzt->setAction(funzt, vza[i]);
    152303      }
     
    161312      cout << "***zthr Threads Z1 ... Z" << N << " Finished OK" << endl;
    162313      cout << res;
     314      cout << " Resu: getDataSize() = " << res.getDataSize() << "  getStackSize()="
     315           << res.getStackSize() << endl;
    163316      for(int i=0; i<N; i++) {
    164317        delete vzth[i];
    165318        delete vza[i];
     319      }
     320      if (mtvp) {
     321        Timer tm("MTVecPool::Check()");
     322        mtvp->Check();
     323        tm.Nop();
     324        delete mtvp;
    166325      }
    167326    }
Note: See TracChangeset for help on using the changeset viewer.