Hello, I'm trying to do a re indexing using threads, but according to tests under Windows Vista, Quarda Intel Core, 4 Gig RAM, the tests are not entirely satisfactory;
The basic idea was to determine the number of threads that want to implement, N_THREADS, which is passed by parameter, for testing purposes. Well, times; 1 thread = 29 minutes THE WINNER! 4 threads = 93 minutes WoW! 7 threads = 68 minutes 5 Threads = 64 minutes Something to do this by penalizing Harbour indexing, or the code above, you have thing excessively penalized. ---------------- SPANISH ------------------------------------------- Hola, Estoy intentando hacer una re indexación usando hilos, pero según pruebas bajo Windows Vista, Intel Quard Core, 4 Gigas RAM, los test no son del todo satisfactorios; La idea básica es determinar la cantidad de hilos que queremos poner en marcha, N_THREADS, que es pasado por parámetro, para poder realizar pruebas. Pues bien, los tiempos ; 1 Hilo = 29 minutos THE WINNER! 4 Hilos = 93 minutos WoW!! 7 hilos = 68 minutos 5 Hilos = 64 minutos Algo hacer Harbour que esta penalizando la indexación, o el código expuesto, tiene alguna cosa que penaliza en exceso. Cualquier comentario es bienvenido para mejorar este aspecto. //---------------------------------------------- source code ---------------------------------------------------------- /* Example multiThreads index. One thread by table , and one thread by index. 2010 Rafa Carmona Thread Main |---------> table for test.dbf | |----> Thread child index fname | | | |----->Thread child index fcode c:\> ..\..\bin\win\bcc\hbmk2 -mt indexthread -lhbcpage -Le:\harbour\trunk\harbour\lib\win\bcc New code, now, if thread dead, new thread create! */ #include "hbclass.ch" #include "hbthread.ch" #include "common.ch" #include "inkey.ch" #include "FileIO.ch" REQUEST HB_CODEPAGE_ES850, HB_CODEPAGE_ES850C REQUEST HB_LANG_ES static N_THREADS := 5 STATIC nTecla STATIC s_num_procesos STATIC s_aLineas := { } static s_hMutex static s_hHandle_File static s_nCount_Errores := 0 proc Main( nHilos ) Local nSeconds Local cDbf, lProcesa := .F. Local aFicheros, x Local aDbfs, aNtxs, aKeys , aDesc, aFor, aSel Local aThreads := {} Local nProceso := 0, nLinea, lSalir := .F., nIndex Local nLen_Table Local nPosTable, cCadena, cLine, aTokens, i Local nPos_Column := 1, g DEFAULT nHilos TO 0 if !empty( nHilos ) N_THREADS := val( nHilos ) endif //HB_SetCodePage( "ES850" ) En xHarbour set( _SET_CODEPAGE, "ES850C" ) HB_LANGSELECT('ES') Set( _SET_LANGUAGE, "ES" ) setmode( 25,130 ) cls @01,0 SAY padc( hb_ansitooem( " Indexación multihilo. Rafa Carmona" ), 80 )COLOR "N*/W*" @23,0 SAY padc( "Pulse ESC para cancelar." , 80) COLOR "R+/N" // ONLY for TEST, if necesary many many DBF , with millions records for test. // My test is over 200 dbfs, with 12GB total size, without NTX. aDbfs := { "test", "test2" } // Arrays files dbf aNtxs := { { "fname", "fcode" },; // files index for test { "fName2" } } // files index for test2 aKeys := { { "name", "code" },; { "dtos(fecha)+str(code)" } } // Expresions aFor := { { "", ""}, {""} } nLen_Table := len( aDbfs ) nPosTable := 1 nSeconds := Seconds() s_num_procesos := 0 s_hMutex := hb_mutexCreate() s_hHandle_File := FCreate( "indexpms.log" ) for g := 1 to N_THREADS // Posicion en la columa por cada numero de hilo aadd( s_aLineas, nPos_Column ) nPos_Column += 16 next while nPosTable <= nLen_Table if ( nTecla := inkey() ) = K_ESC exit endif if N_THREADS = s_num_procesos // No se ha muerto ningun proceso loop endif cDbf := aDbfs[ nPosTable ] if file( cDbf+".dbf" ) hb_mutexLock( s_hMutex ) s_num_procesos++ hb_mutexUnLock( s_hMutex ) hb_threadStart( @aCreateIndexe(), cDbf, aNtxs[ nPosTable ], aKeys[ nPosTable ], aFor[ nPosTable ] ) endif nPosTable++ end while @23,1 SAY "Espere, terminado reindexaciones pendientes..." + space( 50 ) COLOR "R*/N" hb_threadWaitForAll() // Esperamos a los ultimos. @23,1 SAY "Proceso de indexacion terminado..." + Str( (Seconds() - nSeconds) /60 ) + space( 50 ) COLOR "W+/N" FClose( s_hHandle_File ) return function aCreateIndexe( cFile, aNtx, aExpr, aFor ) Local nContador := 1 Local cFileNtx, cExpr Local aThreads := {} Local cAlias, cFor Local nP, x, oError, lreturn := .f. use ( cFile ) if neterr() hb_mutexLock( s_hMutex ) s_num_procesos-- s_nCount_Errores++ hb_mutexUnLock( s_hMutex ) @22,1 SAY "[ "+ alltrim( str( s_nCount_Errores ))+" ] Error de apertura en el fichero : "+ cFile + space( 10 ) fwrite( s_hHandle_File, "Error de apertura en el fichero : "+ cFile + Hb_OsNewline() ) return nil endif cAlias := alias() hb_dbDetach( cAlias ) // Libero el alias for x := 1 to len( s_aLineas ) nPosLinea := s_aLineas[ x ] if !empty( nPosLinea ) s_aLineas[x] := 0 // Quita del array esa linea disponible para pintar exit endif next @ 2, nPosLinea CLEAR TO 15, nPosLinea + 14 // Limpiamos cuadrado hb_dispOutAt( 2, nPosLinea , cFile ) for each cFileNtx in aNtx cExpr := aExpr[ cFileNtx:__enumindex ] cFor := aFor[ cFileNtx:__enumindex ] nPos := cFileNtx:__enumindex delete file ( cFileNtx +".ntx") // Se borra el fichero, por ahorro de espacio en disco. aadd( aThreads, hb_threadStart( @crea(), cAlias,cExpr, cFileNtx, cFor, nPos, nPosLinea ) ) if ( nTecla := inkey() ) = K_ESC // No protegemos variable static exit endif next aEval( aThreads, { |x| hb_threadJoin( x ) } ) // Espera que termine los hilos hijos hb_dbRequest( cAlias, , , .T.) // Restaura el alias close // Vuelve a colocar la linea como disponible para pintar s_aLineas[x] := nPosLinea hb_mutexLock( s_hMutex ) s_num_procesos-- hb_mutexUnLock( s_hMutex ) RETURN .T. proc crea( cAlias, cExpr, cFileNtx, cFor, nPos, nPosLinea ) Local nContador := 1 hb_dbRequest( cAlias, , , .T.) // Restaura el alias if empty( cfor ) INDEX ON &(cExpr) TO &(cFileNtx) ; EVAL {|| hb_dispOutAt( nPos +3, nPosLinea, padr( cFileNtx,8 )+ "-"+alltrim( hb_valtostr( nContador) ), "GR+/N" ), nContador += INT( LASTREC() / 100 ) , .T. } ; EVERY INT( LASTREC() / 100 ) // EVAL {|| hb_dispOutAt( nPos +2, nPosLinea, padr( cFileNtx,8 )+ "-"+ padr( cExpr,20)+ " # " +alltrim( hb_valtostr( nContador) ), "GR+/N" ), nContador += INT( LASTREC() / 100 ) , .T. } ; else INDEX ON &(cExpr) TO &(cFileNtx) FOR &(cFor) ; EVAL {|| hb_dispOutAt( nPos +3, nPosLinea, padr( cFileNtx,8 )+ "-"+alltrim( hb_valtostr( nContador) ), "GR+/N" ), nContador += INT( LASTREC() / 100 ) , .T. } ; EVERY INT( LASTREC() / 100 ) endif hb_dbDetach( cAlias ) // Libera el alias return _______________________________________________ Harbour mailing list (attachment size limit: 40KB) Harbour@harbour-project.org http://lists.harbour-project.org/mailman/listinfo/harbour