Changeset 3177 in Sophya for trunk/SophyaProg
- Timestamp:
- Feb 6, 2007, 9:19:44 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SophyaProg/Tests/zthr.cc
r3080 r3177 7 7 8 8 #include "tmatrix.h" 9 #include "tvector.h" 9 10 #include "tarrinit.h" 10 11 … … 18 19 csh> time zthr mtx 2 500 19 20 csh> time zthr arr 2 500 21 csh> time zthr sync 4 1000 20 22 */ 21 23 … … 24 26 25 27 #include "timing.h" 28 #include "ctimer.h" 26 29 27 30 28 31 // --- Structure d'argument pour fonction d'execution dans les threads de test 29 32 typedef struct { 30 int thid;31 int M;33 int_4 thid; 34 int_4 M; 32 35 } ztarg; 33 36 … … 91 94 92 95 96 // Structure de gestion utilisee par la classe MTVecPool 97 typedef 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 // ------------------------------------------------------------------- 106 class MTVecPool { 107 public: 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 205 static MTVecPool* mtvp = NULL; 206 207 // --- fonction de test avec synchronisation entre threads 208 void 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 } 93 235 94 236 class CountLock : public ZMutex { … … 103 245 static int N = 1; 104 246 static int M = 5; 247 static int VSZ = 128; 105 248 106 249 int main(int narg, char *arg[]) … … 109 252 110 253 if (narg < 4) { 111 cout << " Usage: zthr select N LM " << endl;254 cout << " Usage: zthr select N LM [Sz] " << endl; 112 255 cout << " select= sl -> simple loop with sleep " << endl; 113 256 cout << " select= mtx -> matrix init and multiply mx1*mx2" << endl; 114 257 cout << " select= arr -> array/matrix init and operation c1*a1+c2*a2 " << endl; 115 258 cout << " select= clk -> Mutex lock count " << endl; 259 cout << " select= sync -> Thread synchronisation using ZMutex" << endl; 116 260 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; 118 263 return(1); 119 264 } 120 265 121 266 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")) { 123 269 cout << "zthr/erreur argument sel (!= sl / mtx / arr / clk) " << endl; 124 270 return 2; … … 128 274 N = atoi(arg[2]); 129 275 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; 131 279 132 280 … … 136 284 int rc = 0; 137 285 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); 140 289 vector<ztarg *> vza; 141 290 vector<ZThread *> vzth; … … 145 294 ztarg* zap = new ztarg; 146 295 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; 148 298 vza.push_back(zap); 149 299 if (sel == "mtx") pzt->setAction(mtx_funzt, vza[i]); 150 300 else if (sel == "arr") pzt->setAction(arr_funzt, vza[i]); 301 else if (sel == "sync") pzt->setAction(sync_funzt, vza[i]); 151 302 else pzt->setAction(funzt, vza[i]); 152 303 } … … 161 312 cout << "***zthr Threads Z1 ... Z" << N << " Finished OK" << endl; 162 313 cout << res; 314 cout << " Resu: getDataSize() = " << res.getDataSize() << " getStackSize()=" 315 << res.getStackSize() << endl; 163 316 for(int i=0; i<N; i++) { 164 317 delete vzth[i]; 165 318 delete vza[i]; 319 } 320 if (mtvp) { 321 Timer tm("MTVecPool::Check()"); 322 mtvp->Check(); 323 tm.Nop(); 324 delete mtvp; 166 325 } 167 326 }
Note:
See TracChangeset
for help on using the changeset viewer.