diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index 6bb9480f1efaf50a041da82b2386ec6e3edc0887..d1af1a867b6afcb9b66ac70f1907ca599ccc77a2 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -80,7 +80,7 @@ //ALBERTO CONCEPT FORK //CONTROL CENTER bool singleMode = false; -bool debugMessage = false; +bool debugMessage = true; //CONTROL CENTER //GLOBAL VARIABLES @@ -89,6 +89,8 @@ bool father; //TRUE IF THE PROCESS IS NOT A CHILD int threadNumber; //NUMBER OF THREAD IF WE ARE IN A CHILD int posActualNode = 0; //NODE THAT IS BEING PROCESSED bool ignore_vector; //IGNORE THE VECTOR IF WE ARE UNDER A SPLIT THAT IS NOT QUATERNARY +int NumberOfThreads = 6; //NUMBER OF THREADS CREATED +int repartLevelNumber = 0; //NUMBER IN WHICH THREAD REPART IS PERFORMED //GLOBAL VARIABLES //TOSTRING_VECTOR @@ -344,40 +346,119 @@ void EncCu::createSharedVector() ftruncate(fd, VECTOR_BYTES + sizeof(sem_t)); vector = (vectorModeCostStruct*) mmap(NULL, VECTOR_BYTES, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); } +void EncCu::repartLevel() +{ + for(int i=0; i<5; i++) + { + if(levelValues[i]>=NumberOfThreads) + { + repartLevelNumber = i; + break; + } + + } +} +int EncCu::repartStart() +{ + int repartStartNode = 0; + for(int i=0; i<= repartLevelNumber-1; i++) + { + repartStartNode += levelValues[i]; + } + return repartStartNode; +} +int EncCu::repartEnd() +{ + int repartEndNode = -1; + for(int i=0; i<= repartLevelNumber; i++) + { + repartEndNode += levelValues[i]; + } + return repartEndNode; +} +void EncCu::initStructVectorBeforeRepartStart(int repartStartNode) +{ + for(int i=0; i=(LEVEL0) && posPadreActual<=(LEVEL1)) //Estamos en el nivel 1 + { + updateFatherAndThreadNumbers(0,1,posPadreActual,i,1,childCounter,thread1ChildNumber,threadNumber,numberOfNodesPerThread); + } + else if(posPadreActual>=(LEVEL1+LEVEL0) && posPadreActual<=(LEVEL2+LEVEL1)) //Estamos en el nivel 2 + { + updateFatherAndThreadNumbers(1,2,posPadreActual,i,2,childCounter,thread1ChildNumber,threadNumber,numberOfNodesPerThread); + } + else if(posPadreActual>=(LEVEL2+LEVEL1+LEVEL0) && posPadreActual<=(LEVEL3+LEVEL2+LEVEL1)) //Estamos en el nivel 3 + { + updateFatherAndThreadNumbers(2,3,posPadreActual,i,3,childCounter,thread1ChildNumber,threadNumber,numberOfNodesPerThread); + } + } +} +void EncCu::updateFatherAndThreadNumbersLevel0(int posPadreActual, int thread1ChildNumber, int numberOfNodesPerThread) +{ + if(repartLevelNumber==1) //Estamos en el nivel 0, el padre realiza el reparto de threads { int salto = 1; int threadNumber = 1; int start = posPadreActual+salto; int end = posPadreActual+salto+4; + int childCounter = 1; for(int j=start; j=(thread1ChildNumber+1))//Si se han rellenado todos los del uno avanzamos de thread + { + //Los del ajuste + el primero de los normales + threadNumber++; + } + else if(thread1ChildNumber==-1 && childCounter==(numberOfNodesPerThread)) + { + childCounter = 0; + threadNumber++; + } + childCounter++; } } - else if(posPadreActual>=(LEVEL0) && posPadreActual<=(LEVEL1)) //Estamos en el nivel 1 - { - updateFatherAndThreadNumbers(0,1,posPadreActual,i); - } - else if(posPadreActual>=(LEVEL1+LEVEL0) && posPadreActual<=(LEVEL2+LEVEL1)) //Estamos en el nivel 2 - { - updateFatherAndThreadNumbers(1,2,posPadreActual,i); - } - else if(posPadreActual>=(LEVEL2+LEVEL1+LEVEL0) && posPadreActual<=(LEVEL3+LEVEL2+LEVEL1)) //Estamos en el nivel 3 + else { - int posPadreEnNivel = i-LEVEL2-LEVEL1-LEVEL0; - int salto = (LEVEL3-posPadreEnNivel)+4*posPadreEnNivel; //Saltos sobre los hermanos derechos del padre + Saltos sobre hijos izquierdos no del padre - int threadNumber = vector[i].threadNumber; + int salto = 1; + int threadNumber = 1; int start = posPadreActual+salto; int end = posPadreActual+salto+4; for(int j=start; j-1;j--) + if(LevelActualIndex+1 == repartLevelNumber) //SI ESTAMOS EN EL PADRE DEL NIVEL DONDE SE HACE EL REPARTO { - LevelLow += levelValues[j]; + int LevelLow = 0; + int LevelUp = levelValues[LevelUpIndex]; + for(int j=LevelLowIndex; j>-1;j--) + { + LevelLow += levelValues[j]; + } + int posPadreEnNivel = i-LevelLow; + int salto = (LevelUp-posPadreEnNivel)+4*posPadreEnNivel; //Saltos sobre los hermanos derechos del padre + Saltos sobre hijos izquierdos no del padre + //int threadNumber = 1; //vector[i].threadNumber;//Comenzamos en el thread 1 + int start = posPadreActual+salto; + int end = posPadreActual+salto+4; + for(int j=start; j(thread1ChildNumber+numberOfNodesPerThread) && (childCounter-thread1ChildNumber)%numberOfNodesPerThread==0) + { + threadNumber++; + } + childCounter++; + } + + } - int posPadreEnNivel = i-LevelLow; - int salto = (LevelUp-posPadreEnNivel)+4*posPadreEnNivel; //Saltos sobre los hermanos derechos del padre + Saltos sobre hijos izquierdos no del padre - int threadNumber = vector[i].threadNumber; - int start = posPadreActual+salto; - int end = posPadreActual+salto+4; - for(int j=start; j-1;j--) + { + LevelLow += levelValues[j]; + } + int posPadreEnNivel = i-LevelLow; + int salto = (LevelUp-posPadreEnNivel)+4*posPadreEnNivel; //Saltos sobre los hermanos derechos del padre + Saltos sobre hijos izquierdos no del padre + int threadNumber = vector[i].threadNumber; + int start = posPadreActual+salto; + int end = posPadreActual+salto+4; + for(int j=start; jlastModeAvailable(*tempCS, partitioner) && tempCS->cost == MAX_DOUBLE); //SI SOLO QUEDA UN MODO Y EL COSTE ES MÁXIMO, NO PODEMOS SKIPEAR bool skipMode = (!singleMode && father && vector[posActualNode].mode!=-1 && vector[posActualNode].mode!=currTestMode.type && !ignore_vector && vector[posActualNode].mode!=ETM_RECO_CACHED && !lastModeAvailable); - bool skipCU = (!singleMode && !father && 1<=posActualNode && posActualNode<=4 && vector[posActualNode].threadNumber!=threadNumber);//SI ESTAMOS EN UN THREAD INCORRECTO SE HACE SKIP + bool skipCU = (!singleMode && !father && /*1<=posActualNode && posActualNode<=4 &&*/ vector[posActualNode].threadNumber!=threadNumber);//SI ESTAMOS EN UN THREAD INCORRECTO SE HACE SKIP if(debugMessage) { std::cout << "posActualNode:" << posActualNode << ", Vector:" << vector[posActualNode].mode << ", CurrMode:" << currTestMode.type << std::endl;} if(skipMode) { @@ -977,7 +1090,7 @@ bool activeIgnoreVector = false; (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()) || #endif (m_pcEncCfg->getSmoothQPReductionEnable()) || -#if ENABLE_QPA_SUB_CTU +#if ENABLE_QPA_SUB_CTUskipCU (m_pcEncCfg->getUsePerceptQPA() && !m_pcEncCfg->getUseRateCtrl() && pps.getUseDQP()) #else false diff --git a/source/Lib/EncoderLib/EncCu.h b/source/Lib/EncoderLib/EncCu.h index 18334e96a63249c6d5ab834e82b90f5c9f5e5e75..61a55dea0b4eb0593ce16fed1e2950f4fdd9db6e 100644 --- a/source/Lib/EncoderLib/EncCu.h +++ b/source/Lib/EncoderLib/EncCu.h @@ -326,8 +326,14 @@ public: //ALBERTO CONCEPT FORK void createSharedVector(); + void repartLevel(); + int repartStart(); + int repartEnd(); + void initStructVectorBeforeRepartStart(int repartStartNode); + int thread1NumberOfChild(int numberOfNodesPerThread); void initStructVector(); - void updateFatherAndThreadNumbers(int LevelLowIndex, int LevelUpIndex, int posPadreActual, int i); + void updateFatherAndThreadNumbersLevel0(int posPadreActual,int thread1ChildNumber,int numberOfNodesPerThread); + void updateFatherAndThreadNumbers(int LevelLowIndex, int LevelUpIndex, int posPadreActual, int i,int LevelActualIndex,int& childCounter,int thread1ChildNumber,int& threadNumber,int numberOfNodesPerThread); void cleanCostModeVector(); // END ALBERTO CONCEPT FORK